Почему мы используем пустые get; set; accessors в C#? [дубликат]

Возможные Дубликаты:
c#: почему пустые свойства get set вместо использования открытой переменной-члена?

string name;

vs

string name {get; set;}

предполагая, что ваши get и set пусты, как указано выше, какой смысл их указывать?

8 ответов


он инкапсулирует сгенерированное компилятором поле и предоставляет вам class или struct разработчик возможность обновить его внутри позже, не нарушая API, просто изменив get/set часть, о которой вы заботитесь.

например, внезапно никогда не хотите вернуться null? Вы можете сделать это, просто изменив пустой get to get { return storedName ?? ""; }. Конечно, это означает, что вам внезапно нужно вручную управлять переменной, но это небольшая цена за гибкость.


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

это вообще плохая практика, чтобы обеспечить прямой доступ к полю. Тем не менее, команда .NET заметила, что многие геттеры/сеттеры в основном именно это. Например, рассмотрим следующее:

// C#
public string Name
{
    get { return name; }
    set { name = value; }
}

// Without properties (or a Java implementation)
public void setName(String name)
{
    this.name = name;
}

public String getName()
{
    return name;
}

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

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

рассмотрим следующий пример:

public string Name
{
    get;
    set;
}

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

private string name;
public event NameChangingEventHandler NameChanging;
public event NameChangedEventHandler NameChanged;

public string Name
{
    get { return name; }
    set
    {
        OnNameChanging(/*...*/);
        name = value;
        OnNameChanged(/*...*/);
    }
}

protected virtual void OnNameChanging(/*...*/) { }
protected virtual void OnNameChanged(/*...*/) { }

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

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


первый на самом деле поле, но второй-это автоматически реализуемое свойство. Разница между ними уже обсуждалось.


первый, предполагая, что он объявлен в области класса, является именем Поля. Он доступен как поле. Вторая-собственность. Пустой get / set известен как auto-свойство.


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


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

но даже тогда, есть еще один очень убедительная причина предоставлять свойства только в общедоступных интерфейсах: даже если вам никогда не нужно делать никаких внутренних обновлений, использование полей все равно может привести к другим проблемам в будущем, потому что многие части .NET framework сильно предпочитают свойства полям. Например, WPF обычно не поддерживает привязку к полям. Вы можете обойти это, делая причудливые вещи, такие как реализация ICustomTypeDescriptor, но гораздо проще просто ввести {get; set;}.


string name {get; set;}

Это называется автоматически реализуемого свойства. На самом деле, C# создает переменную, начиная с_, поэтому на get, это значение переменной извлекается и на set, это значение переменной устанавливается. Его так же, как обычные свойства. Где string name; это просто поле.


первый-переменная, второй-свойство (shorthanded)


свойства очень хороши, но, как правило, объекты не должны выставлять состояние общественности; они должны быть черным ящиком с точки зрения посторонних. И особенно не стоит заявлять о прямых изменениях. Состояние должно измениться как побочный эффект запроса экземпляра объекта сделать что-то полезное в проблемной области.

Если вы собираетесь выставить состояние, выставьте его как свойство только для чтения (например,public widget Foo { get ; private set ; }).