С# - проверка инициализации переменной
Я хочу проверить, инициализирована ли переменная во время выполнения программно. Чтобы причины этого были менее загадочными, см. Следующий неполный код:
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
тоже будет "Занзибаром"? Тогда у меня есть ошибка. Любой лучший способ?
Ответы
Ответ 1
Код даже не компилируется, если компилятор знает, что переменная не была инициализирована.
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
}
}
В документации указано, что значение по умолчанию (T) даст null
для ссылочных типов и 0
для типов значений. Так, как указано в комментариях, это действительно так же, как проверка на нуль.
Все это скрывает тот факт, что вы должны действительно инициализировать переменные, null
или что-то еще, когда они впервые объявлены.
Ответ 2
С С# 2.0 у вас есть оператор Nullable, который позволяет вам установить начальное значение null для всех типов значений, позволяющее использовать такие вещи, как:
int? x = null;
if (x.HasValue)
{
Console.WriteLine("Value for x: " + num.Value);
}
Что дает:
"Значение для x: Null".
Ответ 3
Просто назначьте его null
по умолчанию, а не строковое значение
Ответ 4
Здесь один из способов:
string s;
if (someCondition) { s = someValue; }
else if (someOtherCondition) { s = someOtherValue; }
else { throw new Exception("Please initialize s."); }
Console.WriteLine(s)
Это может быть предпочтительным для проверки, является ли строка нулевой, потому что возможно someValue - это метод, который иногда может возвращать значение null. Другими словами, возможно, null является законным значением для инициализации строки.
Лично мне нравится это лучше, чем флаг isInitialized
. Зачем вводить дополнительную переменную флага, если вам не нужно? Я не думаю, что это более читаемо.
Ответ 5
Вы можете сохранить отдельный флаг, который указывает, что строка была инициализирована:
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
более четко выражает ваше намерение.
Ответ 6
Я выбираю значения инициализации, которые никогда не могут использоваться, типичные значения включают String.Empty
, null
, -1
и генератор случайных строк в 256 символов.
Ответ 7
В общем случае назначьте значение по умолчанию null
или String.Empty
. В ситуациях, когда вы не можете использовать эти "пустые" значения, определите константу для представления неинициализированного значения для конкретного приложения:
const string UninitializedString = "zanzibar";
Затем укажите это значение, когда вы хотите инициализировать или проверить для инициализации:
string foo = UnininitializedString;
if (foo == UninitiaizedString) {
// Do something
}
Помните, что строки являются неизменяемыми константами в С#, поэтому на самом деле существует только один экземпляр UninitializedString
(поэтому это сравнение работает).