Инициализация или не инициализация переменной в C # зависит от того, чего вы хотите достичь, и оба параметра действительны в разных ситуациях.
Возьмем, к примеру, класс, который предоставляет некоторые свойства, и вы хотите, чтобы свойства имели значение по умолчанию:
public class X
{
private object _propertyName;
public object PropertyName
{
get { return _propertyName; }
set
{
_propertyName = value;
doSomething();
}
}
}
В этом классе, оставив _propertyName
неинициализированным, вы можете получить NullReferenceException
, если вы попытаетесь прочитать значение свойства до того, как оно было установлено, поэтому инициализация его подходящим значением по умолчанию - хорошая практика 1008 *
Однако иногда вы хотите предоставить пользователю возможность передать null
, и в этом случае инициализация переменной может перезаписать этот допустимый ввод.
public void doSomethingToObjectInCollection(object key, List<object> haystack)
{
// First find it in the collection
object foundValue;
for( int i = 0; i < haystack.Count; i++ )
{
if( haystack[i].KeyField == key )
foundValue = key;
}
if( foundValue != null )
{
// Do something here if there was a foundValue
}
}
В этом примере инициализация foundValue значением по умолчанию создаст неправильное поведение. Конечно, вы можете инициализировать его явно null
, если вам так трудно на это смотреть, но это не меняет поведения кода (в отличие от C ++).
Что касается соображений производительности, к сожалению, нет ответа «да, это плохо» или «нет, все в порядке». В большинстве приложений это, вероятно, не будет иметь большого значения, но если у вас есть жесткие требования к производительности, то для решения, что делать, требуется контекстно-зависимое понимание того, что именно происходит при инициализации переменной.
Типы значений будут инициализироваться при присвоении нулю, но это вряд ли дорогостоящая операция, и, вероятно, она не будет чрезмерно беспокоить вас.
Справочные типы - это то место, где вы можете понизить производительность, инициализируя значения перед их использованием. Например:
public class TheClass
{
MyType x = new MyType();
public TheClass()
{
x = new MyType(/*some arguments*/);
}
}
Это приведет к двум выделениям для x, первое с конструктором по умолчанию, второе внутри конструктора с новыми значениями. Это потому, что переменные уровня класса инициализируются перед конструктором.