Разница между нулевым и не инициализированным? - PullRequest
9 голосов
/ 23 февраля 2011

Когда я пишу следующий код на C #:

SqlCeCommand command;
try
{
    // The command used to affect the data
    command = new SqlCeCommand
                  { 
                     // init code removed for brevity
                  };

    // Do stuff 
    // Do more stuff
}
finally
{
    if (command != null)
        command.Dispose();
}

Решарпер жалуется на мою проверку команды! = Null.В нем говорится, что команда не может быть назначена (потому что она может каким-то образом потерпеть неудачу в построении и все же попасть в блок try).

Поэтому я изменяю объявление команды на SqlCeCommand command = null;, и все довольны.

Но мне интересно, в чем разница?

И почему по умолчанию он не равен нулю? Значение: Каким образом C # выигрывает не от того, что локальные переменные по умолчанию обнуляются?

Ответы [ 6 ]

8 голосов
/ 23 февраля 2011

Локальные переменные не имеют значения по умолчанию.Часть языка.

5 голосов
/ 23 февраля 2011

Ну, если вы хотите, чтобы он был нулевым, вам нужно сообщить об этом. Это для ловли ошибок. Компилятор и такие утилиты, как ReSharper, ищут все пути выполнения и следят за тем, чтобы переменные были инициализированы до их использования. Это чтобы поймать типичные ошибки кодирования. Таким образом, никакое дополнительное значение «даже не нулевое» возможно, это всего лишь анализ, выполненный компилятором (или чем-то еще), чтобы помочь вам.

Члены класса инициализируются значениями по умолчанию (например, null для ссылочных типов), поэтому вы получаете ожидаемое поведение.

3 голосов
/ 23 февраля 2011

Это связано с целью C # обеспечить правильность кода.В объявлении класса (в отличие от локальных переменных) члены имеют неявные значения, поэтому вам не нужно явно устанавливать их в объявлении или конструкторе класса.В контексте функции / метода, однако, C # отслеживает, была ли переменная явно установлена, так что она может предупреждать вас о таких вещах, как то, что вы видите ... это решение о разработкечасть языка.

1 голос
/ 23 февраля 2011

Вы можете написать эквивалентный, но более компактный код с помощью конструкции using, которая вызывает для вас Dispose:

using (var command = new SqlCeCommand
       { 
           // init code removed for brevity
       })
{

    // Do stuff 
    // Do more stuff
}

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

0 голосов
/ 23 февраля 2011

Члены поля класса получают значения по умолчанию (типы значений каждый в зависимости от своего типа, а типы ссылок равны нулю), а локальные переменные - нет.

// Example 1:
SomeClass someObject;
if(x == y)
{
    someObject = new SomeClass();
}
someObject.someMethod();   //Error since it may not execute the if statements

// Example 2
SomeClass someObject;
someObject = new SomeClass();
someObject.someMethod();   //No Error

РЕДАКТИРОВАТЬ: Это было разработано, чтобы избежать ошибок времени выполнения C ++, которые вызывали неожиданное закрытие программы (из-за нулевых указателей).

P.S .: Вы не можете меня опускать, когда я говорю о спецификациях C # (я не делал спецификаций C #, хотя я приветствую это избегание).

0 голосов
/ 23 февраля 2011

Вы можете проверить на нулевое значение, так как нулевое значение является значением. Не инициализированный означает отсутствие значения, поэтому вы не можете проверить его.

...