C# - проверка инициализации переменной

Я хочу проверить, если переменная инициализируется во время выполнения программно. Чтобы сделать причины этого менее загадочными, см. Следующий неполный код:

string s;

if (someCondition) s = someValue;
if (someOtherCondition) s = someOtherValue;

bool sIsUninitialized = /* assign value correctly */;

if (!sIsUninitialized) Console.WriteLine(s) else throw new Exception("Please initialize s.");

и завершите соответствующий бит.

одно хакерское решение-инициализировать s со значением по умолчанию:

string s = "zanzibar";

а затем проверьте, изменилось ли оно:

bool sIsUninitialized = s == "zanzibar";

однако, что если someValue или someOtherValue случилось быть "Занзибар" также? Тогда у меня жучок. Любой товар способ?

7 ответов


код не будет даже компилироваться, если компилятор знает, что переменная не была инициализирована.

string s;
if (condition) s = "test";
// compiler error here: use of unassigned local variable 's'
if (s == null) Console.Writeline("uninitialized");

в других случаях вы можете использовать default ключевое слово, если переменная не была инициализирована. Например, в следующем случае:

class X
{ 
    private string s;
    public void Y()
    {
        Console.WriteLine(s == default(string));  // this evaluates to true
    }
}

на документация заявляет, что default (T) даст null для ссылочных типов, и 0 для типов значений. Так что, как указано в комментариях, это действительно то же самое, что и проверка ноль.


все это скрывает тот факт, что вы действительно должны инициализировать переменные, чтобы null или что-то еще, когда они впервые объявлены.


С C# 2.0 у вас есть оператор Nullable, который позволяет установить начальное значение null для типов значений heretofore, позволяя такие вещи, как:

int? x = null;

if (x.HasValue)
{
    Console.WriteLine("Value for x: " + num.Value); 
}

, который дает: "Значение для x: Null".


просто назначить null по умолчанию не строковое значение


вот так:

string s;
if (someCondition) { s = someValue; }
else if (someOtherCondition) { s = someOtherValue; }
else { throw new Exception("Please initialize s."); }

Console.WriteLine(s)

это может быть предпочтительнее для проверки, является ли строка null, потому что, возможно, someValue-это метод, который иногда может возвращать null. Другими словами, возможно, null является законным значением для инициализации строки.

лично мне это нравится больше, чем isInitialized флаг. Зачем вводить дополнительную переменную флага, если вам это не нужно? Я не думаю, что это более читабельным.


вы можете сохранить отдельный флаг, который указывает, что строка инициализации:

string s = null;
bool init = false;
if (conditionOne) {
    s = someValueOne;
    init = true;
}
if (conditionTwo) {
    s = someValueTwo;
    init = true;
}
if (!init) {
    ...
}

это позаботится о ситуациях, когда s назначается, включая случаи, когда он назначается null, пустая строка или "zanzibar".

другое решение-сделать статическую строку для обозначения "неопределенного" значения, и использовать Object.ReferenceEquals вместо == чтобы проверить, если он был изменен. Однако bool переменный подход выражает ваше намерение a намного яснее.


Я выбираю значения инициализации, которые никогда не могут быть использованы, типичные значения:String.Empty, null, -1 и 256-символьный генератор случайных строк .


В общем, назначьте значение по умолчанию null или String.Empty. В ситуациях, когда вы не можете использовать эти "пустые" значения, определите константу для представления вашего неинициализированного значения приложения:

const string UninitializedString = "zanzibar";

затем ссылаться на это значение всякий раз, когда вы хотите инициализировать или тест на инициализации:

string foo = UnininitializedString;
if (foo == UninitiaizedString) {
  // Do something
}

помните, что строки являются неизменяемыми константами в C#, поэтому на самом деле существует только один экземпляр UninitializedString (именно поэтому сравнение работает).