Частный 'набор' в C# - имеющий проблему, переносящую мой мозг вокруг этого

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

public class Test
{
   public object Thingy { get; private set; }
}

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

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

19
задан Steven Sudit 22 July 2010 в 20:45
поделиться

9 ответов

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

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

EDIT: Просто решил привести пример. Автоматические свойства отлично подходят для чистого, лаконичного кода. Но, как вы показали, есть ограничение в том, что вам нужно иметь get и set. Поэтому раньше для свойства, как вы показали, это выглядело так:

public class Test
{
   private object thingy;
   public object Thingy
   {
      get { return thingy; }
   }
}

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

Я знаю, что это было излишнее объяснение, но у меня в голове постоянно всплывают разные вещи.

24
ответ дан 30 November 2019 в 03:07
поделиться

По сути, это свойство readonly. Если бы оно было написано полностью (не как свойство auto), вы бы просто убрали сеттер.

Два одинаковых примера:

class Foo1
{
   public int Id { get; private set; }
   public Foo1()
   {
       Id = lastId ++;
   }
}

class Foo2
{
   private int _id;  // could be readonly 
   public int Id { get { return _id; } }
   public Foo2()
   {
       _id = lastId ++;
   }
}
2
ответ дан 30 November 2019 в 03:07
поделиться

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

4
ответ дан 30 November 2019 в 03:07
поделиться

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

Другим примером может быть список:

public List<Foo> Items {get;private set;}

, поскольку мы можем вызвать obj.Items.Add () и т. Д., Но мы редко назначаем obj.Items = ... . Однако этот пример омрачен необходимостью явной инициализации в конструкторе, и XmlSerializer ненавидит это - честно говоря, для списков, которые я в основном использую:

private readonly List<Foo> items = new List<Foo>();
public List<Foo> Items {get { return items;}}

, который решает обе эти проблемы.

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

private readonly int foo;
public int Foo {get{return foo;}}

vs

private readonly int foo;
public int Foo {get{return foo;} private set {foo=value;}}

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

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

9
ответ дан 30 November 2019 в 03:07
поделиться

Я видел, как это использовалось с дизайном:

public class whatever
{
    public string WhateverId { get; private set; }

    public static whatever Create(string whateverId)
    {
        return new whatever() { WhateverId = whateverId };
    }
}

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

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

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

public void SetWhateverId(string whateverId)
{
    DisconnectAllCurrentWhateverIdReferences();
    WhateverId = whateverId;
    ReconnectAllPreviousWhateverIdReferences();
}
2
ответ дан 30 November 2019 в 03:07
поделиться

Чтобы ответить на вопрос о распространенном сценарии, где это может быть использовано... В шаблоне MVP, если ваша Модель раскрывает некоторые свойства для вашего Ведущего, я бы написал

public string Bazinga { get; private set; }

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

0
ответ дан 30 November 2019 в 03:07
поделиться

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

struct Point
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public Point(int x, int y)
    {
        this = default(Point);
        X = x;
        Y = y;
    }
}
1
ответ дан 30 November 2019 в 03:07
поделиться

Это просто лень , возникающая из-за авто-свойств. До появления автоматических свойств люди реализовывали метод получения и опускали сеттер для свойств, предназначенных только для чтения.

public class Test
{
   private /*readonly*/ Type _thingy;
   public Type Thingy { get { return _thingy; } }
}

Надеюсь, C # 5 позволит вам создавать автоматические свойства только с помощью геттера - потому что этого хотят все. (Они также должны делать сеттеры только для чтения в auto-props, мне это очень нужно)

0
ответ дан 30 November 2019 в 03:07
поделиться

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

1
ответ дан 30 November 2019 в 03:07
поделиться
Другие вопросы по тегам:

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