Я понимаю, что это похоже на дубликат статьи В чем разница между полем и свойством в C #? но мой вопрос имеет небольшую разницу (с моей точки зрения):
Как только я это узнаю
- Я не буду использовать свой класс с «техниками, которые работают только со свойствами» и
- Я не буду использовать код проверки в геттере / сеттере.
Есть ли разница (кроме стиля / будущего развития), например, какой-то тип управления при установке свойства?
Есть ли дополнительная разница между:
public string MyString { get; set; }
а также
public string myString;
(Я знаю, что для первой версии требуется C # 3.0 или выше, и что компилятор действительно создает частные поля.)
Ответы:
Инкапсуляция.
Во втором случае вы только что определили переменную, в первом для переменной есть геттер / сеттер. Так что, если вы решите, что хотите проверить переменную позже, это будет намного проще.
К тому же они по-другому отображаются в Intellisense :)
Изменить: обновление для обновленного вопроса OP - если вы хотите игнорировать другие предложения здесь, другая причина в том, что это просто нехороший дизайн OO. И если у вас нет веских причин для этого, всегда выбирайте свойство вместо общедоступной переменной / поля.
источник
Поля и свойства выглядят одинаково, но это не так. Свойства - это методы, и поэтому есть определенные вещи, которые не поддерживаются для свойств, а также некоторые вещи, которые могут происходить со свойствами, но не в случае полей.
Вот список отличий:
out/ref
аргументов. Свойства не могут.DateTime.Now
не всегда равно самому себе.readonly
)MemberTypes
поэтому они расположены по-разному ( например,GetFields
vsGetProperties
)источник
Пара быстрых, очевидных отличий
Свойство может иметь ключевые слова-аксессоры.
public string MyString { get; private set; }
Свойство можно переопределить в потомках.
public virtual string MyString { get; protected set; }
источник
Принципиальное отличие состоит в том, что поле - это позиция в памяти, где хранятся данные указанного типа. Свойство представляет собой один или два блока кода, которые выполняются для получения или установки значения указанного типа. Использование этих методов доступа синтаксически скрыто с помощью члена, который ведет себя как поле (в том смысле, что он может появляться с любой стороны операции присваивания).
источник
Аксессоры - это больше, чем поля. Другие уже указали на несколько важных отличий, и я собираюсь добавить еще одно.
Свойства принимают участие в интерфейсных классах. Например:
interface IPerson { string FirstName { get; set; } string LastName { get; set; } }
Этот интерфейс может быть удовлетворен несколькими способами. Например:
class Person: IPerson { private string _name; public string FirstName { get { return _name ?? string.Empty; } set { if (value == null) throw new System.ArgumentNullException("value"); _name = value; } } ... }
В этой реализации мы защищаем как
Person
класс от перехода в недопустимое состояние, так и вызывающий объект от получения значения NULL из неназначенного свойства.Но мы могли продвинуть дизайн еще дальше. Например, интерфейс может не иметь дело с сеттером. Вполне правомерно сказать, что потребителей
IPerson
интерфейса интересует только получение свойства, а не его установка:interface IPerson { string FirstName { get; } string LastName { get; } }
Предыдущая реализация
Person
класса удовлетворяет этому интерфейсу. Тот факт, что он позволяет вызывающей стороне также устанавливать свойства, не имеет смысла с точки зрения потребителей (которые потребляютIPerson
). Дополнительная функциональность конкретной реализации учитывается, например, конструктором:class PersonBuilder: IPersonBuilder { IPerson BuildPerson(IContext context) { Person person = new Person(); person.FirstName = context.GetFirstName(); person.LastName = context.GetLastName(); return person; } } ... void Consumer(IPersonBuilder builder, IContext context) { IPerson person = builder.BuildPerson(context); Console.WriteLine("{0} {1}", person.FirstName, person.LastName); }
В этом коде потребитель не знает об установщиках свойств - это не его дело. Потребителю нужны только геттеры, а геттеры он получает из интерфейса, то есть из контракта.
Другой вполне допустимой реализацией
IPerson
будет неизменяемый класс person и соответствующая фабрика person:class Person: IPerson { public Person(string firstName, string lastName) { if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) throw new System.ArgumentException(); this.FirstName = firstName; this.LastName = lastName; } public string FirstName { get; private set; } public string LastName { get; private set; } } ... class PersonFactory: IPersonFactory { public IPerson CreatePerson(string firstName, string lastName) { return new Person(firstName, lastName); } } ... void Consumer(IPersonFactory factory) { IPerson person = factory.CreatePerson("John", "Doe"); Console.WriteLine("{0} {1}", person.FirstName, person.LastName); }
В этом примере кода потребитель снова не знает, как заполнять свойства. Потребитель имеет дело только с геттерами, а конкретная реализация (и стоящая за ней бизнес-логика, например, тестирование, если имя пусто) предоставляется специализированным классам - разработчикам и фабрикам. Все эти операции с полями совершенно невозможны.
источник
Первый:
public string MyString {get; set; }
это собственность; второй (
public string MyString
) обозначает поле.Разница в том, что некоторые методы (привязка данных ASP.NET для экземпляров) работают только со свойствами, а не с полями. То же верно и для сериализации XML: сериализуются только свойства, поля не сериализуются.
источник
Свойства и поля во многих случаях могут показаться похожими, но это не так. Есть ограничения на свойства, которые не существуют для полей, и наоборот.
Как уже упоминали другие. Вы можете сделать свойство доступным только для чтения или только для записи, сделав его закрытым для доступа. С полем этого не сделать. Свойства также могут быть виртуальными, а поля - нет.
Думайте о свойствах как о синтаксическом сахаре для функций getXXX () / setXXX (). Вот как они реализуются за кадром.
источник
Есть еще одно важное различие между полями и свойствами.
При использовании WPF вы можете выполнять привязку только к общедоступным свойствам. Привязка к общедоступному полю работать не будет . Это верно, даже если не реализовано
INotifyPropertyChanged
(даже если вы всегда должны это делать).источник
Среди других ответов и примеров я думаю, что этот пример полезен в некоторых ситуациях.
Например, скажем, у вас есть следующее:
OnChange
property
public Action OnChange { get; set; }
Если вы хотите , чтобы делегаты использования , чем вам необходимо изменить его ,
OnChange
чтобыfield
это нравится:public event Action OnChange = delegate {};
В такой ситуации мы защищаем наше поле от нежелательного доступа или изменения.
источник
Вы всегда должны использовать свойства вместо полей для любых общедоступных полей. Это гарантирует, что ваша библиотека будет иметь возможность реализовать инкапсуляцию для любого поля, если это потребуется в будущем, без нарушения существующих кодов. Если вы замените поля свойствами в существующих библиотеках, тогда все зависимые модули, использующие вашу библиотеку, также необходимо перестроить.
источник