2013-06-18 5 views
6

У меня есть следующий метод, определенный в классе:Локальная переменная (целое) не может быть инициализирован перед обращением к

public bool LogOff(string sessionId) 
{ 
    int res; 
    // Some non related code here.. 
    if (res == 1) 
    { 
     return true; 
    } 
    return false; 
} 

Что странно для меня является то, что я получаю «Локальная переменная не может быть инициализирована до доступ к "из Visual Studio (у меня установлен ReSharper) в предложении IF. Почему это так, когда «res» - это тип значения, и по умолчанию он должен быть равен 0? Я должен указать, что если я специально установил значение res в 0, тогда все в порядке.

Что мне здесь не хватает? Я думал, что эти основы программирования, но, видимо, я не знаком с основами ...

+0

ошибка говорит вам, что вам нужно сделать, чтобы сделать 'int res = 0' инициализировать его значением – MethodMan

+0

@nvoigt Это не дубликат, потому что этот пример имеет дело со ссылочным типом DateTime, в то время как этот вопрос касается типов значений но нормально ... – Marko

+0

@Marko Оба значения и ссылочные типы имеют значение по умолчанию. Оба испускают эту ошибку, если они явно не установлены. Для этого сообщения нет никакой разницы между значением и ссылочным типом. В принятом ответе также не упоминается какая-либо разница в этом случае. Поэтому для меня это дубликат. – nvoigt

ответ

8

Ответ на вопрос «почему C# работает таким образом» неизменно «потому что это то, что в спецификации». Раздел 5.3.2 спецификации языка C# перечислены переменные, которые первоначально не присвоенные:

  • Instance variables of initially unassigned struct variables.
  • Output parameters, including the this variable of struct instance constructors.
  • Local variables, except those declared in a catch clause or a foreach statement.

Относительно того, почему это ошибка, раздел 5.3 состояния

A variable must be definitely assigned at each location where its value is obtained.

Если инициализировать значение как int res = new int();, вы получите значение по умолчанию, равное нулю. Более общий способ упоминается в других ответах, который заключается в том, чтобы установить его равным нулю. Опора на значения по умолчанию делает код менее читаемым без реальных преимуществ.

+0

Это ответ, который я искал ... Спасибо !!! – Marko

+1

@ Марко Рад помочь. Специфика языка часто игнорируется как ресурс, но на самом деле это достаточно читаемо и полезно, когда вы занимаетесь этими вопросами. Вы можете даже купить аннотированную копию для дальнейшего уточнения. –

8

Why is this the case when "res" is a value type and as such should default to 0?

Даже при том, что значение по умолчанию равно 0 в полях членов, местные жители требуют явного задания значения. Компилятор предупредит вас, что вы используете его без его инициализации, поскольку это, скорее всего, ошибка.

Хотя это «технически» может быть прекрасным с нулевым инициализированным значением по умолчанию с логической точки зрения, с реальной точки зрения, тот факт, что вы никогда не устанавливали значение перед его проверкой, либо 1) бесполезен (if никогда не будет правдой) или 2) ошибка (вы хотели установить значение, но что-то изменилось).

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

I should point out that if I specifically set the value of res to 0 then it's all OK.

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

+0

Это не предупреждение. Я не могу построить решение. Я получаю эту ошибку: использование неназначенной локальной переменной «res» ... Это то, что меня смущает ... – Marko

+1

@Marko Locals! = Fields - вы должны инициализировать локальную переменную перед их использованием. Компилятор рассматривает это как ошибку вместо «просто обрабатывать ее», потому что это общий источник реальных ошибок. –

+1

@ Марко Я думаю, что путаница проистекает из-за того, что поведение разных типов. Внутри типа (то есть: поле) тип значения получает нуль-инициализируется. Локальные члены внутри метода не обязательно имеют такое поведение - язык требует, чтобы вы присвоили им какое-то значение. –

1

Проблема заключается в том, что неинициализированное значение не гарантируется 0 на C#. В соответствии с language specification неинициализированные переменные могут не использоваться, поскольку C# предназначен для предотвращения того, что вы делаете явно плохие вещи.

Основная причина, по которой некоторые другие языки (в частности, C и C++) do позволяют это сделать, потому что это дополнительная работа над писателем компилятора для обнаружения и флага этого условия.

EDIT: Here является соответствующей частью # языка спецификации C:

+0

Что значит, что это не гарантируется? Как может быть не так, если это тип значения? Каково значение объявленного int, когда я сам не определяю значение по умолчанию? – Marko

+1

Это зависит от того, как реализована среда CLR. Если он явно не обнуляет эту память, тогда это будет то, что было в последний раз сохранено в физическом местоположении в памяти, в котором содержится ваша переменная. –

+0

Значит, есть какая-то ценность? Может ли это значение быть нулевым? Я до сих пор не понимаю, почему бы не позволить мне строить, если значение будет что-то, даже если это 12345 ... – Marko

2

C# требует, чтобы все переменные должны быть инициализированы перед использованием. Для таких локальных переменных вам необходимо их инициализировать явно. Поля в структуре или классе не обязательно должны быть инициализированы явно, потому что они получают значение по умолчанию как часть построения объекта.

Так вот, вам просто нужно сделать

int res = 0; 

и все будет хорошо.

0

Инициализация по умолчанию применяется к членам класса/структуры, которая здесь не применяется, поскольку res является локальной переменной; как переменная, а не элемент данных, применяется «инициализация, требуемая до использования».

Смежные вопросы