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

Возьмите private string Property {get; set;} против private string field.

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

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

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


person Andreas Grech    schedule 27.05.2011    source источник


Ответы (5)


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

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

person Henk Holterman    schedule 27.05.2011

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

ОБНОВИТЬ

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

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

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

person Aliostad    schedule 27.05.2011
comment
Имеет ли смысл частная собственность, поскольку они, скорее всего, используются для доступа к частному полю? - person Xaisoft; 27.05.2011
comment
Когда вы компилируете «релиз» - ›без следа и с оптимизацией, это НЕ повлияет на производительность для автосвойств. - person MajesticRa; 27.05.2011

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

person vines    schedule 27.05.2011
comment
Я думал об этом, но было бы разумно сказать, что по этой причине всегда использовать свойства вместо частных членов? - person Andreas Grech; 27.05.2011
comment
@ Андрей Греч: Я полагаю, это зависит от обстоятельств. Бывают случаи, когда член достаточно определенно, например какое-то временное / вспомогательное / флаговое / любое значение, а есть случаи, когда я бы тоже рассмотрел свойства. - person vines; 27.05.2011
comment
Если самый чистый способ кодирования требует получения ref члену (например, чтобы его можно было передать Interlocked методам), использование свойства может привести к использованию более неуклюжего дизайна. Если по каким-либо причинам использование свойства в конечном итоге окажется неизбежным, тогда может быть лучше начать с неуклюжего дизайна, чем реализовывать систему с чистым дизайном, а затем заменять его неуклюжим, когда поле заменен на собственность. С другой стороны, если член никогда не должен быть свойством, было бы лучше использовать более чистый дизайн. - person supercat; 03.04.2013

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

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

person InBetween    schedule 27.05.2011
comment
«бесполезно, что я вижу», вы действительно не правы. Смотрите мой пост почему. - person MajesticRa; 27.05.2011
comment
@MajesticRa: Я вижу, вы не полностью прочитали мой ответ. Я считаю автоматические частные свойства бесполезными, потому что вы не можете добавить к ним какую-либо собственную логику. В самом деле, как я упоминал в своем ответе, единственное, что я могу найти для частных свойств, - это централизовать некоторую логику состояния вашего класса, но тогда они не могут быть автоматическими, как предполагал OP. - person InBetween; 27.05.2011

Свойства ЯВЛЯЮТСЯ функциями.
Поля - это "переменные, по крайней мере, с видимостью класса".

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


Отличие от точки производительности:

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

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

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

Отличие от дизайнерского взгляда:

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

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

 class Hand
 {
     public int fingersNumber;
 }

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

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

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

 class Hand
 {
     public int fingersNumber;
     public int ringsNumber;

 }

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

 leftHand.fingersNumber-- 

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

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

 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--;

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

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

person MajesticRa    schedule 27.05.2011
comment
Я ценю ваш пространный ответ, но мой вопрос был не о свойствах и полях в целом. Я спрашивал, есть ли семантическая разница между использованием частного свойства и использованием частного поля, и я специально сказал, что свойство не использует дополнительную проверку. - person Andreas Grech; 27.05.2011
comment
Формально разницы нет. Если вы видите разборку, если вы используете оптимизацию и запускаете без трассировки, автосвойства будут обрабатываться как встроенные автоматически сгенерированные поля. Так что разницы в микропроизводительности нет. - person MajesticRa; 27.05.2011
comment
НО свойства позволяют ДОБАВИТЬ барьеры проверки или памяти на дальнейших этапах разработки. Поля нет. Это главное. - person MajesticRa; 27.05.2011
comment
Я знаю, я не спорю с тобой. Я знал, что вы сказали о недвижимости, до того, как спросил об этом, и мой вопрос совершенно не связан с этим. Итак, помимо проверки, в чем основное различие между частным полем и частной собственностью? - person Andreas Grech; 28.05.2011