2012-02-04 2 views
0

Прошу прощения, если эта тема будет считаться субъективной, но мой вопрос больше связан с технической стороны.C# Vars init, исполнение и хорошая практика

Я работаю с C# в Framework .Net 4.0. Я провел несколько лет, играя с C++, и я получил образование, в котором переменные, которые не были инициализированы, заставили меня ударить в задницу.

Сегодня, каждый раз, когда я вижу неинициализированную переменную в фрагменте C#, я немного дрожу, и я действительно не могу решить, должен ли я их инициализировать или нет.

Я читал много статей, в которых люди говорят, что некоторые из них инициализированы, другие нет (члены против локального), я читал статьи, в которых люди говорят, что инициализация vars на C# вызывает у вас проблемы с производительностью ...

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

Какова наилучшая практика в отношении этого?

Edit:

public MyClass 
{ 
    private int foo; // Is it initialized ? Do I have to ? 

    public void MyMethod() 
    { 
     int bar; // Is it initialized ? Do I have to ? 

     ... 
    } 
} // Is it a good practice to initialize every vars all the time or not ? 
    // Will I get troubles by not initializing those ? 
    // If I do initialize them, will I get performance slowdown ? 
+1

Проблема заключается не в том, что вопрос субъективен, а в том, что он имеет слишком широкий охват и не очень ясен! Задайте конкретный вопрос, желательно с образцом кода. – Oded

+0

Прошу прощения, что вы не понимаете в моем вопросе? Я хочу знать, если в C# все переменные автоматически инициализируются или если есть случаи, когда их нет.Затем, я хочу знать, будет ли у меня привычка инициализировать все переменные, чтобы мои выступления снизились ... Это лучше? Спасибо за ваш ответ. –

ответ

1

Я хочу знать, если в C#, все переменные автоматически инициализирован, или если есть некоторые случаи, когда есть не

Когда ты объявите переменную ссылочного типа, например, экземпляр SomeClass, значение по умолчанию будет null. Ваша переменная будет инициализирован, как только вы выделить память для него, используя новый

SomeClass someClass; //not initialized, it's value is null 

someClass = new SomeClass(); //initialized 

На других типах значений вручную инициализируются при объявлении их. Например

int bar; //initialized with value 0 

Это хорошая практика, чтобы инициализировать каждый вары все время или нет?

Хорошо, это зависит от сценария. Например, когда вы объявляете bool, это значение по умолчанию - false. Но для понимания читателя лучше явно сделать bool myBool = false. С другой стороны, если вам нужно передать переменную как out для некоторого метода, инициализация переменной бесполезна, поскольку она несет ответственность за метод. Это действительно зависит от вашего сценария и практики, которые вам нравятся.

Будет ли я получать проблемы, не инициализируя их?

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

Если я инициализирую их, я получу замедление производительности?

Nope. Если производительность вашего приложения очень медленная, вы должны использовать некоторый профилировщик, чтобы узнать, что вызывает медленную производительность.Инициализация переменной очень маловероятна, чтобы вызвать ошибку производительности

+0

Спасибо за ваш ответ. Я читал, что такие вары, как «int bar»; инициализируются только тогда, когда есть члены класса, а не локальные методы, правильно ли это или нет? –

+1

Нет, это неправильно. Int всегда будет инициализирован 0 –

+0

@hansHasan: но для локальной переменной нет возможности узнать программиста. –

3

В C# у вас не будет проблемы с неинициализированными переменными, имеющими случайные значения, как в C/C++.

Некоторые переменные (поля/статика, например) должны быть инициализированы по умолчанию (обычно null/0), а компилятор дает вам an error во всех случаях, когда значение по умолчанию не гарантируется, и вы не вручную инициализируйте переменную перед использованием.

Другими словами, если вы не уверены, доверяйте компилятору рассказать вам.

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

1

Инициализация или не инициализация переменной в C# зависит от того, чего вы хотите достичь, и оба варианта действительны в разных ситуациях.

Возьмем, к примеру, класс, который предоставляет некоторые свойства, и вы хотите свойства иметь значение по умолчанию:

public class X 
{ 
    private object _propertyName; 

    public object PropertyName 
    { 
     get { return _propertyName; } 
     set 
     { 
      _propertyName = value; 
      doSomething(); 
     } 
    } 
} 

В этом классе, оставляя _propertyName неинициализированным может привести вас к NullReferenceException, если вы пытаетесь прочитайте значение свойства до того, как оно будет установлено, поэтому для его правильной инициализации это подходящее значение по умолчанию.

Однако иногда вы хотите предоставить пользователю возможность пройти в 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*/); 
    } 
} 

Это приведет к двум ассигнований на й, первых конструктор по умолчанию, второй внутри конструктора с новыми значениями. Это связано с тем, что переменные уровня класса инициализируются перед конструктором.

+0

Спасибо за ваш ответ. В ответе Хариса Хасана он называет нас примером «int bar». Но я читал, что эти строки типа vars инициализируются только тогда, когда есть члены класса, а не локальные методы, правильно это или нет? –

+0

Как сказано выше, int всегда будет инициализироваться до нуля. Таким образом, инициализация, например, "int x = 5;" приведет к двум назначениям. – ose

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