C # Vars init, производительность и хорошая практика - PullRequest
0 голосов
/ 04 февраля 2012

Извините, если эта тема будет считаться субъективной, но мой вопрос скорее технический.

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

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

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

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

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

Редактировать:

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 ?

Ответы [ 3 ]

3 голосов
/ 04 февраля 2012

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

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

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

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

1 голос
/ 04 февраля 2012

Инициализация или не инициализация переменной в 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, первое с конструктором по умолчанию, второе внутри конструктора с новыми значениями. Это потому, что переменные уровня класса инициализируются перед конструктором.

1 голос
/ 04 февраля 2012

Я хочу знать, если в 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 какому-либо методу, инициализация переменной бесполезна, потому что это ответственность метода. Это действительно зависит от вашего сценария и практики, которой вы хотели бы следовать.

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...