Семантическая разница между свойством и полем и их последствия

Принимать private string Property {get; set;} против private string field,

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

Что касается семантики, имеют ли они разные значения? В том смысле, что они взаимозаменяемы при таком использовании?

И когда дело доходит до последствий, таких как (микро?) Производительность, имеет ли значение, если вы создаете поле вместо свойства, то есть позволяете ли компилятор позаботиться о поле поддержки для вас.

5 ответов

  • Свойство о скрытии данных поля
  • Частная собственность не имеет большого значения, так как тот, кто имеет доступ к собственности, также будет иметь доступ к полю.
  • Нет никакого влияния на производительность для автоматического свойства по сравнению с полем поддержки, так как компилятор выплевывает поле поддержки, но могут быть предупреждения сериализации / десериализации.

ОБНОВИТЬ

Последствия для производительности:

Использование свойства (auto или with backing field) против поля имеет небольшую производительность, поскольку свойство является методом, а CLR virtcall должен быть вызван.

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

Когда они частны, единственное различие, которое я знаю, состоит в том, что собственность не подходит для out а также ref параметры.

Но в основном частная собственность не дает никаких преимуществ (по сравнению с полем), так зачем беспокоиться?
Там, вероятно, (микро) затраты производительности. Я бы больше беспокоился о лишнем беспорядке.

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

Свойства являются функциями.
Поля являются "переменными, по крайней мере, с видимостью класса".

Так что если у вас есть частная собственность против частного поля:


Разница с точки зрения производительности:

нет разницы, если вы используете оптимизацию и нет трассировки (свойства рассматриваются как встроенные).

Разница в семантике:

1) Формально без разницы.
2) Более глубоко, есть разница. Поскольку свойства являются функциями, вы МОЖЕТЕ получить делегат от getter и setter. И МОЖЕТ использовать делегата как... делегата, например, помещая этот делегат в список вместе с другими делегатами ( создайте делегат из метода получения или установки свойства)

Отличие от дизайна:

Но свойства - это функции, которые выглядят как переменные. Зачем нужны функции, которые выглядят как переменные?

Допустим, у вас есть класс Hand, и эта рука имеет переменную fingerNumber.

 class Hand
 {
     public int fingersNumber;
 }

Тогда у вас может быть много кода, как

 if(he is BadPerson) leftHand.fingersNumber--
 if(doctor.Heal()) leftHand.fingersNumber++

Но в какой-то момент вы можете захотеть добавить в Hand другую переменную. Допустим, это кольца. И вы знаете, что вы не можете иметь более 10 колец на каждый палец.

 class Hand
 {
     public int fingersNumber;
     public int ringsNumber;

 }

Теперь вы не можете просто сделать

 leftHand.fingersNumber-- 

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

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

 class Hand
 {
     private int fingersNumber;
     private int ringsNumber; 
     public int GetFingersNumber(){...check logic...}
     public void SetFingersNumber(int value){...check logic...}
     public int GetRingsNumber(){...check logic...}
     public void SetRingsNumber(int value){...check logic...}
 }

И использовать эту функцию как

 if(he is BadPerson) leftHand.SetFingersNumber(leftHand.GetFingersNumber()-1)

Проблема здесь в том, что старый код leftHand.fingersNumber-- не будет работать сейчас. И с самого начала вы не знали бы, что в будущем добавят кольца. Для решения проблем стало парадигмой устанавливать поля как частные и использовать функции Set и Get для получения и изменения переменных, и УБЕДИТЕСЬ, что в будущем можно добавить туда любую логику, и код будет работать!

Сеттеры и геттеры - это текущая ситуация в C++, Java и многих языках. Но создатели C# пошли дальше и назвали такие функции получения и установки "свойствами".

 class Hand
 {
     private int fingersNumber; 
     public int FingersNumber
     {
          get{return fingersNumber;}
          set{fingersNumber=value;}
     }
     ...     
  }
  ...
  if(he is BadPerson) leftHand.FingersNumber--;

Но большую часть времени люди создают такое простое свойство, и, как вы видите на примере, это 5 строк обычного кода. Поэтому в некоторых версиях C# были добавлены авто свойства, чтобы упростить жизнь программистам. Так что ваш класс, вероятно, выглядит

 class Hand
 {
     public int FingersNumber{get;set;}
 }

но в любое время вы можете расширить это поведение get set:

  class Hand
 {
     private int fingersNumber; 
     public int FingersNumber
     {
          get{...check logic...}
          set{...check logic...}
     }

     ...     
  }

И это не будет тормозить любой код. подобно

  if(he is BadPerson) leftHand.FingersNumber--;

Так вот, что это за свойства, почему они используются и в чем разница с полями.

Также, как я упоминал ранее, простые свойства и свойства авто имеют такую ​​же производительность, как и переменные, если вы используете оптимизацию. Се разборка или просто гугл по этому поводу.

Создание частного автоматического свойства не имеет смысла, который я вижу. Если он не автоматический, его можно использовать как своего рода внутренний "обработчик событий", чтобы поддерживать состояние объекта в актуальном состоянии: выполнять некоторые действия каждый раз, когда поле изменяется (через установщик) в любом месте кода.

Спектакль? Я не думаю, что будет проблема, даже на микро-микро уровне.

Другие вопросы по тегам