Там какие-либо причины состоят в том, чтобы использовать частные собственности в C#?

Я просто понял, что конструкция свойства C# может также использоваться с частным модификатором доступа:

private string Password { get; set; }

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

private string _password;

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

private string Password { get; }

или

private string Password { set; }

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

Кто-либо использует частные собственности в C# по какой-либо причине или является этим только одна из тех конструкций technically-possible-yet-rarely-used-in-actual-code?

Приложение

Хорошие ответы, прочитывая их я отобрал это использование для частных собственностей:

  • когда частные поля должны быть лениво загружены
  • когда частные поля нуждаются в дополнительной логике или вычисляются значения
  • так как частные поля может быть трудно отладить
  • для "представления контракта себе"
  • внутренне преобразовать/упростить выставленное свойство как часть сериализации
  • обертывание глобальных переменных, которые будут использоваться в классе
225
задан 3 revs 22 July 2010 в 04:41
поделиться

12 ответов

Я использую их, если мне нужно кэшировать значение и я хочу отложить его загрузку.

private string _password;
private string Password
{
    get
    {
        if (_password == null)
        {
            _password = CallExpensiveOperation();
        }

        return _password;
    }
}
196
ответ дан 23 November 2019 в 03:55
поделиться

Одна вещь, которую я делаю все время, это хранение "глобальных" переменных/кэша в HttpContext.Current

private static string SomeValue{
  get{
    if(HttpContext.Current.Items["MyClass:SomeValue"]==null){
      HttpContext.Current.Items["MyClass:SomeValue"]="";
    }
    return HttpContext.Current.Items["MyClass:SomeValue"];
  }
  set{
    HttpContext.Current.Items["MyClass:SomeValue"]=value;
  }
}
6
ответ дан 23 November 2019 в 03:55
поделиться

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

Если это просто прямое защитное поле? Ничего не приходит в голову как веская причина.

2
ответ дан 23 November 2019 в 03:55
поделиться

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

2
ответ дан 23 November 2019 в 03:55
поделиться

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

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

5
ответ дан 23 November 2019 в 03:55
поделиться

Свойства и поля не однозначны. Свойство относится к интерфейсу класса (будь то открытый или внутренний интерфейс), а поле - о реализации класса. Свойства не следует рассматривать как способ просто раскрыть поля, их следует рассматривать как способ раскрыть намерение и цель класса.

Точно так же, как вы используете свойства, чтобы представить своим потребителям контракт о том, что составляет ваш класс, вы также можете представить контракт себе по очень похожим причинам. Так что да, я использую частные свойства, когда это имеет смысл. Иногда частное свойство может скрыть детали реализации, такие как отложенная загрузка, тот факт, что свойство действительно представляет собой совокупность нескольких полей и аспектов или что свойство необходимо виртуально создавать при каждом вызове (подумайте DateTime.Now ]). Определенно бывают случаи, когда имеет смысл принудить это даже к себе в бэкэнде класса.

10
ответ дан 23 November 2019 в 03:55
поделиться

Единственное применение, о котором я могу думать

private bool IsPasswordSet 
{ 
     get
     {
       return !String.IsNullOrEmpty(_password);
     }
}
12
ответ дан 23 November 2019 в 03:55
поделиться

Одно из хороших применений для свойств private get only - это вычисляемые значения. Несколько раз у меня были свойства, которые были приватными readonly и просто выполняли вычисления над другими полями моего типа. Это недостойно метода и не интересно другим классам, поэтому это частное свойство.

18
ответ дан 23 November 2019 в 03:55
поделиться

Ленивая инициализация - одно из мест, где они могут быть аккуратными, например,

private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */);

private MyType MyType { get { return this.mytype.Value; } }

// In C#6, you replace the last line with: private MyType MyType => myType.Value;

Тогда вы можете написать: this.MyType везде, а не this.mytype.Value и инкапсулировать тот факт, что он лениво инстанцируется в одном месте.

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

20
ответ дан 23 November 2019 в 03:55
поделиться

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

Я лично использую это, даже когда мне не нужна логика в getter или setter свойства. Использование свойства, даже приватного, помогает защитить ваш код на будущее, чтобы вы могли добавить логику в getter позже, если потребуется.

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


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

public string Password 
{
    get; 
    private set;
}

Это дает вам публичный геттер, но сохраняет сеттер приватным.

42
ответ дан 23 November 2019 в 03:55
поделиться

Основное использование этого в моем коде - ленивая инициализация, как уже упоминалось другими.

Другая причина, по которой частные свойства преобладают над полями, заключается в том, что частные свойства намного проще отлаживать, чем частные поля. Я часто хочу знать такие вещи, как «это поле устанавливается неожиданно; кто первый вызывающий, который устанавливает это поле?» и это будет намного проще, если вы можете просто поставить точку останова на сеттер и нажать go. Вы можете поставить логин туда. Вы можете поместить туда показатели производительности. Вы можете ввести проверки согласованности, которые выполняются в отладочной сборке.

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

131
ответ дан 23 November 2019 в 03:55
поделиться

Я использую их при сериализации, с помощью таких вещей, как DataContractSerializer или protobuf-net, которые поддерживают это использование (XmlSerializer не поддерживает). Это полезно, если вам нужно упростить объект как часть сериализации:

public SomeComplexType SomeProp { get;set;}
[DataMember(Order=1)]
private int SomePropProxy {
    get { return SomeProp.ToInt32(); }
    set { SomeProp = SomeComplexType.FromInt32(value); }
}
8
ответ дан 23 November 2019 в 03:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: