В чем разница между полем и свойством? - PullRequest
971 голосов
/ 17 ноября 2008

Что в C # отличает поле от свойства и когда следует использовать поле вместо свойства?

Ответы [ 30 ]

5 голосов
/ 29 декабря 2013

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

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

вот демо

class Employee
{
    // Private Fields for Employee
    private int id;
    private string name;

    //Property for id variable/field
    public int EmployeeId
    {
       get
       {
          return id;
       }
       set
       {
          id = value;
       }
    }

    //Property for name variable/field
    public string EmployeeName
    {
       get
       {
          return name;
       }
       set
       {
          name = value;
       }
   }
}

class MyMain
{
    public static void Main(string [] args)
    {
       Employee aEmployee = new Employee();
       aEmployee.EmployeeId = 101;
       aEmployee.EmployeeName = "Sundaran S";
    }
}
5 голосов
/ 15 августа 2015

Второй вопрос здесь, «когда следует использовать поле вместо свойства?», Только кратко затронут в этом другом ответе и вроде и этом тоже , но не очень много деталей.

В общем, все остальные ответы на тему хорошего дизайна: предпочитайте выставлять свойства, а не выставлять поля. Хотя вы, вероятно, не будете регулярно ловить себя на мысли: "Ого, представьте, насколько хуже было бы, если бы я сделал это поле вместо свойства", это намного реже подумать о ситуации, когда вы скажете: «Ух ты, слава Богу, я использовал здесь поле вместо свойства».

Но есть одно преимущество, которое поля имеют над свойствами, и это их способность использоваться в качестве параметров "ref" / "out". Предположим, у вас есть метод со следующей подписью:

public void TransformPoint(ref double x, ref double y);

и предположим, что вы хотите использовать этот метод для преобразования массива, созданного следующим образом:

System.Windows.Point[] points = new Point[1000000];
Initialize(points);

Вот, я думаю, самый быстрый способ сделать это, поскольку X и Y - это свойства:

for (int i = 0; i < points.Length; i++)
{
    double x = points[i].X;
    double y = points[i].Y;
    TransformPoint(ref x, ref y);
    points[i].X = x;
    points[i].Y = y;
}

И это будет очень хорошо! Если у вас нет измерений, которые доказывают обратное, нет никаких причин вонять. Но я считаю, что технически не гарантировано, что он будет так быстр:

internal struct MyPoint
{
    internal double X;
    internal double Y;
}

// ...

MyPoint[] points = new MyPoint[1000000];
Initialize(points);

// ...

for (int i = 0; i < points.Length; i++)
{
    TransformPoint(ref points[i].X, ref points[i].Y);
}

Выполняя некоторые измерения , версия с полями занимает около 61% времени как версия со свойствами (.NET 4.6, Windows 7, x64, режим выпуска, отладчик не подключен). Чем дороже становится метод TransformPoint, тем меньше становится разница. Чтобы повторить это самостоятельно, бегите с закомментированной первой строкой и без закомментированной.

Даже если для вышеуказанного не было выигрыша в производительности, есть другие места, где может быть полезна возможность использования параметров ref и out, например, при вызове Interlocked или Volatile семейство методов. Примечание. В случае, если это новость для вас, Volatile - это, по сути, способ получить то же поведение, которое обеспечивает ключевое слово volatile. Таким образом, как и volatile, он волшебным образом не решает всех проблем безопасности потоков, так как его название предполагает, что он мог бы.

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

2 голосов
/ 01 ноября 2013

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

2 голосов
/ 10 августа 2015

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

  class SomeClass
  {
     int numbera; //Field

     //Property 
    public static int numbera { get; set;}

  }
2 голосов
/ 26 июня 2009

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

Однажды я работал в месте, где рекомендуемой практикой было использование открытых полей вместо свойств, когда эквивалентное свойство def просто обращалось к полю, как в:

get { return _afield; }
set { _afield = value; }

Их аргументация заключалась в том, что публичное поле может быть преобразовано в собственность позже в будущем, если потребуется. В то время мне это показалось немного странным. Судя по этим постам, похоже, что не многие здесь согласятся. Что вы могли бы сказать, чтобы попытаться что-то изменить?

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

2 голосов
/ 09 декабря 2016

Мой дизайн поля заключается в том, что поле должно быть изменено только его родителем, следовательно, классом. В результате переменная становится закрытой, чтобы иметь возможность дать право читать классы / методы за ее пределами, я прохожу через систему свойств только с Get. Затем поле извлекается свойством и доступно только для чтения! Если вы хотите изменить его, вы должны пройти через методы (например, конструктор), и я считаю, что благодаря этому способу обеспечения вашей безопасности мы можем лучше контролировать наш код, потому что мы «отбираем». Можно было бы всегда все обнародовать, поэтому каждый возможный случай, понятие переменных / методов / классов и т. Д. ... на мой взгляд, это просто помощь в разработке, поддержке кода. Например, если человек возобновляет код с открытыми полями, он может делать что угодно и, следовательно, «нелогично» по отношению к цели, логике того, почему код был написан. Это моя точка зрения.

Когда я использую классические модели приватных полей / общедоступных свойств только для чтения, для 10 приватных полей я должен написать 10 публичных свойств! Код может быть действительно большим быстрее. Я обнаружил частный сеттер, и теперь я использую общедоступные свойства только с частным сеттером. Сеттер создает в фоновом режиме приватное поле.

Вот почему мой старый классический стиль программирования был:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

Мой новый стиль программирования:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}
2 голосов
/ 17 ноября 2008

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

Таким образом, вы можете сказать, что хотите установить значение только в целочисленное поле, если значение больше x, в противном случае выдается исключение.

Действительно полезная функция.

2 голосов
/ 22 апреля 2015

На этой странице MSDN есть сравнение и советы, которые следует использовать, когда:

https://msdn.microsoft.com/en-us/library/9d65as2e(v=vs.90).aspx

2 голосов
/ 17 ноября 2008

Если вы собираетесь использовать потоковые примитивы, вы вынуждены использовать поля. Свойства могут сломать ваш многопоточный код. Кроме того, то, что сказал Кори, верно.

1 голос
/ 24 октября 2018

Поля - это переменные в классах. Поля - это данные, которые вы можете инкапсулировать с помощью модификаторов доступа.

Свойства аналогичны полям в том смысле, что они определяют состояния и данные, связанные с объектом.

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

...