Почему нам нужны свойства в C # - PullRequest
14 голосов
/ 06 октября 2009

Можете ли вы сказать мне, каково точное использование свойств в C #, я имею в виду практическое объяснение

в нашем проекте мы используем такие свойства, как

/// <summary>
/// column order
/// </summary>
protected int m_order;

/// <summary>
/// Get/Set column order
/// </summary>
public int Order
{
   get { return m_order; }
   set { m_order = value; }
}

/// <summary>
/// constructor
/// </summary>
/// <param name="name">column name</param>
/// <param name="width">column width</param>
/// <param name="order">column order</param>
public ViewColumn(string name, int width, int order)
{
   //
   // TODO: Add constructor logic here
   //
   m_name = name;
   m_width = width;
   m_order = order;
}  


/// <summary>
/// returns the column name, width, and order in list view.
/// </summary>
/// <returns>string represent of the ViewColumn object</returns>
public override string ToString()
{
  return (string.Format("column name = {0}, width = {1}, order = {2}.", 
        m_name, m_width, m_order));
}

/// <summary>
/// Do a comparison of 2 ViewColumn object to see if they're identical.
/// </summary>
/// <param name="vc">ViewColumn object for comparison</param>
/// <returns>True if the objects are identical, False otherwise.</returns>
public override bool Equals(object obj)
{
   ViewColumn vc = (ViewColumn)obj;
   if(m_name == vc.Name &&
        m_width == vc.Width &&
        m_order == vc.Order)
      return true;
   else
      return false;
}

Ответы [ 8 ]

33 голосов
/ 06 октября 2009

Краткий ответ: инкапсуляция

Длинный ответ: свойства очень разнообразны. Это позволяет вам выбирать, как вы хотите представить свои данные для внешних объектов. Вы можете ввести некоторое количество данных для проверки при настройке значений. Он также устраняет головную боль методов getX() и setX(), которые встречаются в Java и т. Д.

24 голосов
/ 06 октября 2009

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

Более техническим ответом будет инкапсуляция, и вы можете проверить этот ответ, чтобы получить больше информации об этом: https://stackoverflow.com/a/1523556/44852

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

Люди попадают в раздел. Довольно легко, проверки не было.

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

теперь вы проверили человека и знаете, есть ли у него что-то злое.

16 голосов
/ 06 октября 2009

Множество причин:

  • Семантика. Свойства отделяют реализацию вашего типа от интерфейса.
  • Двоичная совместимость. Если вам когда-либо понадобится изменить свойство, вы можете сделать это, не нарушая бинарную совместимость для зависимого кода. С полями вы должны перекомпилировать все , даже если новая реализация использует свойство с тем же именем.
  • Databinding. Вы не можете привязать данные к полю.
7 голосов
/ 06 октября 2009

Вот общий шаблон:

class Foo {

    private Bar _bar;

    //here, Foo has a Bar object.  If that object has already been instantiated, return that value.  Otherwise, get it from the database.
    public Bar bar {
        set { _bar = value;}
        get {
            if (_bar == null) {
                _bar = Bar.find_by_foo_name(this._name);
            }
            return _bar;
        }
    }
}

Короче говоря, это позволяет нам получить доступ к объекту Bar в нашем экземпляре Foo.Эта инкапсуляция означает, что нам не нужно беспокоиться о том, как извлекается Bar, или о том, был ли создан экземпляр foo.bar.Мы можем просто использовать объект и позволить внутренним элементам класса Foo позаботиться о нем.

5 голосов
/ 06 октября 2009

Преимущества времени проектирования

Свойства упрощают визуальное проектирование, у вас есть браузер наиболее известных свойств Visual Studio, позволяющий изменять свойства объекта.

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

Отдельные данные и действия

Они действительно представляют разницу между «данными» объекта и «действиями» (методами) объекта.

Когда мы смотрим на класс, если у нас есть 50 методов для просмотра, не все всегда будут использовать правильное именование функций, что затруднит понимание в дальнейшем. Я всегда говорю программистам, что всякий раз, когда вы программируете, пишите код таким образом, чтобы через 5 лет, если кто-то еще смотрит на код, он должен понимать код.

Использование имен методов доступа к данным и некоторых действий создает путаницу в долгосрочной перспективе ... как в случае со стеком, Push / Pop - это действия, а "Size" или "Count" - данные.

Создание свойства «Count» просто различает его назначение как данные вместо действия.

Databinding

Как уже упоминалось, свойства предлагают расширенный уровень привязки данных, такой как двусторонняя привязка и т. Д.

Ограничения доступа

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

Отражение

В случае написания универсального кода, основанного на отражении, работать со свойствами немного сложнее.

Различные реализации хранилища

Публичные переменные хранят данные только как члены, в то время как в других случаях свойства предоставляют различные способы хранения данных в разных формах, например, внутренне они могут храниться как хеш-таблицы (как это делается в объектах зависимостей в WPF). Они могут быть кэшированы. Они могут быть переданы дальше некоторым другим дочерним объектам или внешним объектам. Однако реализация скрыта для абонентов.

проверка

Для настройки свойства может потребоваться определенная проверка, и код проверки в части кода «Установить» может легко помочь вам проверить правильность ввода и сообщить об ошибках соответственно.

Уведомления

Установка части метода может вызывать события уведомления, такие как INotifyPropertyChanged.PropertyChanged, которые другие объекты могут прослушивать и обновлять отображаемое значение. Это важная часть расширенного связывания данных.

Короче говоря, это новый «Стандарт» хранения данных, который имеет расширенные возможности, а затем просто хранит данные в членах класса. Избегая свойств, как правило, вы можете выполнять все функции, но поскольку реализация может отличаться от человека к человеку, это стандарт, который помогает каждому определять / получать доступ / проверять / уведомлять хранилище данных в единой форме, называемой «Свойства»

4 голосов
/ 06 октября 2009

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

4 голосов
/ 06 октября 2009

Как заметил Джастин, инкапсуляция является одним из основных принципов ООП. Вы хотели бы сохранить внутреннее представление данных в вашем классе скрытым извне и предоставить одобренные способы их просмотра / манипулирования.

Свойства C # - это конструкции, которые предоставляют простой способ сделать это. В вашем примере вы ничего не делаете внутри методов get и set, но в реальной жизни вам может понадобиться сделать что-то вроде

  • Храните валюту в десятых центах как длинное целое, но возвращайте во внешний мир в виде строки с 2 десятичными пробелами и знаком $.
  • Ограничить определенное свойство только для чтения (или даже только для записи: например, класс проверки паролей / генератор хэшей).
  • Как-то изменить состояние объекта при установке / получении этого значения.

В Java вы пишете методы получения и установки, которые являются простыми старыми методами, которые возвращают или принимают значение соответственно.

4 голосов
/ 06 октября 2009

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

Это также немного чище для использования:

myObject.Property1 = "Test String";
Console.WriteLine(myObject.Property1);

Чем вы видите на некоторых других языках:

myObject.setProperty1("Test String");
System.out.writeln(myObject.getProperty1());

Вот случай, когда вы можете инкапсулировать некоторую логику:

public int Order
{
    get { return m_order; }
    set
    {
        // Put some rules checking here. Maybe a call to make sure that the order isn't duplicated or some other error based on your business rules.
        m_order = value;
    }
}

Другой способ, которым они полезны, будет выглядеть так:

public int Order { get; private set; }

И теперь у вас есть автоматически реализованное свойство с переменной-членом поддержки, которое можно установить только внутри класса, но читать везде.

Наконец, если вам нужно контролировать логику, вы можете написать это:

public int Order
{
    get { return m_order; }
    protected set
    {
        // Again, you can do some checking here if you want...
        m_order = value;
        // You can also do other updates if necessary. Perhaps a database update...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...