Як використовувати глобальні змінні в C #?


101

Як я можу оголосити змінну, щоб кожен клас (* .cs) мав доступ до свого вмісту без посилання на екземпляр?

Відповіді:


123

У C#ви не можете визначити істинні глобальні змінні (в тому сенсі , що вони не належать ні до одного класу).

Це було сказано, що найпростіший підхід, який я знаю, щоб імітувати цю особливість, полягає у використанні static classнаступного:

public static class Globals
{
    public const Int32 BUFFER_SIZE = 512; // Unmodifiable
    public static String FILE_NAME = "Output.txt"; // Modifiable
    public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}

Потім ви можете отримати визначені значення в будь-якому місці вашого коду (за умови, що це частина того самого namespace):

String code = Globals.CODE_PREFIX + value.ToString();

Щоб мати справу з різними просторами імен, ви можете:

  • оголосити Globalsклас, не включаючи його до конкретного namespace(щоб він був розміщений у глобальному просторі імен додатків);
  • вставити належну директиву використання для отримання змінних з іншої namespace.

@ Заратос чи клас повинен бути статичним?
kosnkov

4
Що ж, це не обов'язково, але я не розумію, навіщо вам це робити.
Томмазо Беллуцо

Якщо вам доведеться інстанціювати його за визначенням вже не "глобальним", не є частиною стану заявки
Вікінг

Привіт, яка б різниця, якби я не вводив статичне ключове слово в класі? Я лише зробив рядок FILE_NAME статичним, я спробував, і він все ще працював на мене.
Томер Кахал

1
Без статичного атрибута ваш клас буде миттєвим (Globals g = новий Globals ()). Це не змінює поведінку статичних змінних, задекларованих всередині, але не виглядає дуже корисною.
Томмазо Беллуццо

74

У C # немає такої речі, як глобальна змінна. Період.

Ви можете мати статичних членів, якщо хочете:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}

Хоча я згоден, чи можете ви, будь ласка, розширити, чому в C # немає такого поняття, як глобальна змінна? Я намагався придумати вагому причину, чому той самий staticприклад, який ви подали, насправді не можна вважати глобальним варом.
Крегокс

3
@cawas тому, що саме поняття "глобальної змінної" (висить нізвідки, пливе в кінцівці, не належить до жодного класу) суперечить самій природі ООП. а C # суто об'єктно орієнтований.
Federico Berasategui

Так, це все поняття, з яким я згоден. Але, зробивши цього статичного члена, ви просто створили своєрідну глобальну вар. Чим це не відрізняється від глобальної вар, про яку ви сказали, не існує? Я хотів би бачити практичний приклад.
Крегокс

1
Я відчуваю, що ви або ухиляєтесь від мого питання, або мені не зрозуміло. Але я вже відповів на це. Тут: stackoverflow.com/a/20010543/274502
cregox

7
Зараз я розумію, що я мав на увазі, що статичні члени - це концептуально і практично глобально варіовані (за винятком, можливо, для цієї купи , що має значення лише за умови, якщо ви не пишете небезпечний код або не робите важкої взаємодії з некерованим кодом ). Тож я не знаю, чому хтось сказав би, що у csharp немає такого поняття, як глобальна змінна . Це мене дуже бентежило.
Крегокс

23

Спершу вивчіть, чи дійсно вам потрібна глобальна змінна, а не використовуйте її нахабно, не враховуючи архітектури вашої програми.

Припустимо, що вона проходить тест. Залежно від використання, Глобалам може бути важко налагодити умови перегонів та багато інших "поганих речей", найкраще підходити до них з тієї точки зору, де ви готові боротися з такими поганими речами. Так,

  1. Оберніть усі такі глобальні змінні в один staticклас (для керованості).
  2. Мати властивості замість полів (= 'змінні'). Таким чином, у вас є деякі механізми для вирішення будь-яких проблем із одночасним записом для Globals у майбутньому.

Основним контуром для такого класу було б:

public class Globals
{
    private static bool _expired;
    public static bool Expired 
    {
        get
        {
            // Reads are usually simple
            return _expired;
        }
        set
        {
            // You can add logic here for race conditions,
            // or other measurements
            _expired = value;
        }
    }
    // Perhaps extend this to have Read-Modify-Write static methods
    // for data integrity during concurrency? Situational.
}

Використання з інших класів (у тому ж просторі імен)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;

4

Корисна функція для цього є using static

Як говорили інші, вам потрібно створити клас для своїх глобальних:

public static class Globals {
    public const float PI = 3.14;
}

Але ви можете імпортувати його так, щоб більше не писати ім’я класу перед його статичними властивостями:

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.