Почему нельзя присвоить значение свойству в теле класса, кроме как в его объявлении?

2

Я надеюсь, что этот вопрос не слишком тупой - я не смог найти ответ, отчасти потому, что я не знаю, как правильно его сформулировать, но я думаю, что небольшой объем кода объяснит это хорошо:

class MyClass
{
    int value = 10;
}

Что именно это делает? При условии

class MyClass    
{
    int value;
    value = 10;
}

не работает (understandably- не имеет смысла присваивать значение члену класса, когда мы не работаем с реальным экземпляром, и этот член не является статическим), поэтому я ожидаю, что первый тоже не работает - но я предполагаю, что это может быть просто краткая запись для "инициализации этого элемента до 10 при создании экземпляра", это правильно?

  • 3
    Это не сработает, это декларация члена, за которой следует какое-то утверждение. Вы не можете иметь такие утверждения в теле определения класса.
  • 1
    Вы можете назначить значение по умолчанию для поля класса, как вы сделали в первом примере. Если вы хотите назначить его где - нибудь, кроме декларации, вы должны сделать это в методе (или свойства). Обычно конструктор используется для назначения значений по умолчанию. Первое назначение работает, потому что оно является частью объявления поля.
Показать ещё 1 комментарий
Теги:

3 ответа

2

Это называется инициализатором поля. Как вы сказали, это просто встроенный ярлык для "инициализации этого элемента до 10 при создании экземпляра".

Инициализация происходит перед вызовом конструктора.

Инициализация поля определяется языком, поэтому компилятор знает, что делать. Операторы в теле класса, такие как значение присваивания = 10, не определяются языком, что приводит к ошибке компилятора. Вот почему второй подход не работает.

1

Я постараюсь дать вам более "продвинутый" ответ, оставаясь при этом в простых терминах.

Оператор, такой как присвоение полю/переменной, должен быть частью тела метода.

Первый пример работает, потому что это трюк с компилятором С#.

Под капотом он устанавливает значение с помощью сгенерированного метода конструктора. Чтобы показать это, я декомпилировал код С# вашего класса в IL, промежуточный язык, к которому он компилируется.

(Я знаю, что код выглядит странно, но это скрытый язык экосистемы .net)

MyClass..ctor: // ctor means constructor
IL_0000:  ldarg.0     
IL_0001:  ldc.i4.s    0A      // 0A is 10 in hexadecimal
IL_0003:  stfld       UserQuery+MyClass.bar
IL_0008:  ldarg.0     
IL_0009:  call        System.Object..ctor
IL_000E:  nop         
IL_000F:  ret 

Ваш второй пример не работает, потому что он не является частью тела метода. С# не может знать, когда его запустить.

Вы можете изменить его на конструктор, который вы создаете сами:

class MyClass
{
    int value;

    public MyClass()
    {
        value = 10;
    }
}
1

Сделайте это так:

class MyClass
{
  MyClass(int value)
 {
  this.value = value; 
 }
}

Позже при создании нового экземпляра:

MyClass classExample = new MyClass(3); // 3 is example value for int value.
// this would set the value to 3 for the "classExample"-instance of class "MyClass".

Альтернативно установка значения по умолчанию:

    class MyClass
{
  MyClass()
 {
  value = 0; // default value would be 0 for all new instances of MyClass. 
 }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню