Есть ли разница в том, инициализирую ли я целочисленную переменную типа:
int i = 0;
int i;
Рассматривает ли это компилятор или CLR как одно и то же? IIRC, я думаю, что их обоих рассматривают как одно и то же, но я не могу найти статью.
Есть ли разница в том, инициализирую ли я целочисленную переменную типа:
int i = 0;
int i;
Рассматривает ли это компилятор или CLR как одно и то же? IIRC, я думаю, что их обоих рассматривают как одно и то же, но я не могу найти статью.
Я посмотрел на IL (используя ildasm) и его true, что только int, установленный в 0, действительно установлен в конструктор 0.
public class Class1
{
int setToZero = 0;
int notSet;
}
Формирует:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: stfld int32 ClassLibrary1.Class1::setToZero
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: ret
} // end of method Class1::.ctor
Если переменная я является переменной экземпляра, ей будет присвоено значение 0 автоматически. Если это локальная переменная в методе, она undefined, поэтому вам нужно будет присвоить ей значение перед ее использованием.
Например:
class Program
{
static void Main(string[] args)
{
intTest it;
it = new intTest();
Console.ReadLine();
}
class intTest
{
int i;
public intTest()
{
int i2;
Console.WriteLine("i = " + i);
Console.WriteLine("i2 = " + i2);
}
}
}
Вышеуказанное не будет компилироваться, потому что i2 не назначен. Однако, назначив 0 на i2, то есть
int i2 = 0;
и компиляция, а затем запуск, покажут, что обе теперь назначены 0.
Да, это в значительной степени одно и то же.
Вы можете обратиться к этой статье в Ужас кодирования
Как сказано в следующей ссылке, они точно такие же:
http://msdn.microsoft.com/en-us/library/aa664742%28VS.71%29.aspx
При всех этих разговорах стоит упомянуть ключевое слово "default" в С#.
т.е. int i;
эквивалентно int i = default(int);
, что эквивалентно int i = 0;
и MyClass o = default(MyClass);
эквивалентно MyClass o = null;
Это особенно актуально при использовании методов linq, таких как .SingleOrDefault()
, потому что вы всегда можете использовать следующее, чтобы сделать ваш код более читаемым:
int someValue = collection.<various linq methods>.SingleOrDefault();
if (someValue == default(int))
{
//Code for the default case
}
и
MyClass someValue = collection.<various linq methods>.SingleOrDefault();
if (someValue == default(MyClass))
{
//Code for the default case
}
Каждый раз, когда вы создаете тип на С#, он автоматически заполняется заполненными нулями. В случае класса (ссылочный тип) это эквивалентно нулевому указателю. Итак, технически, каждый раз, когда вы работаете с классами, следующие идентичны:
MyClass class;
MyClass class2 = null;
С типами значений (любая структура, включая int/float/double/etc), тип передается с нулями, поэтому следующие эквиваленты:
int i;
int j = 0;
Однако в методе компилятор проверяет, назначили ли вы значение вашим типам перед его использованием. Если вы выполните следующее, компилятор будет жаловаться:
int i;
Console.WriteLine{"{0}",i);
Технически, это должно быть хорошо, но поскольку это общий источник ошибки программиста, компилятор специально проверяет неназначенные локальные переменные и жалуется. Однако это жалоба на компиляцию, а не проблема с CLR. Вы можете сделать IL, который делает выше, и он работает нормально.
Они эквивалентны только для полей (переменных класса). Поля автоматически присваиваются значениям по умолчанию при инициализации класса. В рамках метода или свойства неназначенная переменная остается неназначенной и вызывает ошибку компилятора, если вы попытаетесь получить к ней доступ.
Различные ответы здесь несколько вводят в заблуждение, в том числе упоминаемая статья на веб-сайте "Coding Horror".
Компилятор оптимизирует ваш код для удаления всех "ненужных" инициализаций при настройке для оптимизации сгенерированного кода. Обратите внимание, что это поведение по умолчанию при компиляции в режиме "Release".
Я, например, считаю, что всегда очень полезно инициализировать все ваши переменные. Снижение производительности будет минимальным в режиме отладки, и ни один из них не будет доступен в режиме деблокирования, но преимущества явно заданных переменных будут огромными для тех, кто поддерживает код в будущем, в лучшем стиле "документирования кода с кодом". Я помню этого очень опытного коллеги, который считал, что значение по умолчанию Int32 было Int32.MinValue вместо 0. Эти типы путаницы всегда происходят с вещами, подразумеваемыми в коде, и для меня их следует избегать в большинстве случаев.