Я заметил, что фрагмент, подобный приведенному ниже, отмечает инициализацию свойства предупреждением.
public sealed class C(int a)
{
public int A { get; } = a; //<--here
public int Sum(int b)
{
return a + b;
}
}
В предупреждении говорится:
предупреждение CS9124: параметр «int a» фиксируется в состоянии включающий тип и его значение также используются для инициализации поля, собственность или событие.
Однако, если я пропущу дальнейшее использование переменной a, предупреждение исчезнет.
public sealed class C(int a)
{
public int A { get; } = a;
public int Sum(int b)
{
return b; //<-- no more 'a' used here
}
}
Сейчас мне не очень ясна причина предупреждения, хотя у меня есть подозреваемый. Это потому, что в данном случае любая модификация a в классе не изменит свойство A?
@Клеменс, это именно то, что показывает скомпилированный исходный код SharpLab: есть два поля поддержки.





Это происходит потому, что компилятор сгенерирует одно резервное поле для a, используемого в Sum, и другое резервное поле для автоматического свойства A.
Обратите внимание, что a является изменяемым, а A — нет, поэтому вы можете сделать:
public void MutateA(int i) => a += i;
Что повлияет Sum, но не повлияет A:
C c = new C(42);
c.MutateA(7);
Console.WriteLine(c.A); // Prints 42
Console.WriteLine(c.Sum(0)); // Prints 49
public sealed class C(int a)
{
public int A { get; } = a; //<--here
public int Sum(int b)
{
return a + b;
}
public void MutateA(int i) => a += i;
}
Обходным решением/исправлением было бы использование A вместо a в Sum:
public int Sum(int b) => A + b;
Смотрите также:
окей, мой подозреваемый был прав. Однако это предупреждающее сообщение не очень полезно.
да... это тоже самая критикуемая ошибка первоначальных конструкторов. Префикс readonly был бы полезен.
@MarioVernari «Префикс только для чтения был бы полезен». - да, языковая группа AFAIK рассматривает это для следующего выпуска. Но, возможно, это должно было быть поведением по умолчанию.