Семантическая разница между свойством и полем и их последствия
Принимать 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--;
Так вот, что это за свойства, почему они используются и в чем разница с полями.
Также, как я упоминал ранее, простые свойства и свойства авто имеют такую же производительность, как и переменные, если вы используете оптимизацию. Се разборка или просто гугл по этому поводу.
Создание частного автоматического свойства не имеет смысла, который я вижу. Если он не автоматический, его можно использовать как своего рода внутренний "обработчик событий", чтобы поддерживать состояние объекта в актуальном состоянии: выполнять некоторые действия каждый раз, когда поле изменяется (через установщик) в любом месте кода.
Спектакль? Я не думаю, что будет проблема, даже на микро-микро уровне.