Авто-свойства с или без поля поддержки - предпочтение?

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

private int _backingField;

public int Property { get { return _backingField; } }

В чем разница между выше и ниже?

public int Property { get; private set; }

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

Единственное различие, которое я смог найти, заключается в том, что способ вызова значения различается внутри класса, в котором он определен. Это просто предпочтение или есть что-то большее, чтобы вызвать значение через его свойство или прямой доступ к полю? Простые соглашения?

Ответ 1

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

private readonly int _backingField;    
public int Property { get { return _backingField; } }

то есть разница. Код, который я написал выше, не позволяет изменять значение в другом месте внутри класса, тем самым ясно, что это действительно означает, что он является неизменным. Мне бы очень хотелось объявить поле "только для чтения" с автоматическим внедрением свойства "только для чтения", которое может быть установлено только внутри конструктора, но недоступно на данный момент.

Это довольно запутанно, кстати:

Кроме того, я понимаю, что вы должны явно использовать поле backing в случае structs, вы не можете получить доступ к своим членам через свойства.

Что ты имеешь в виду? Вы можете определенно использовать свойства внутри structs. Вы говорите о поддерживающих полях, которые являются изменяемыми структурами, то есть разница между:

foo.someField.X = 10;

и

foo.SomeProperty.X = 10;

? Если это так, я обычно избегаю того, чтобы быть проблемой, заставляя мои структуры неизменно начинать с:)