Подтвердить что ты не робот

Частный "набор" на С# - проблема с моим мозгом вокруг него

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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;}}

против

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

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

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

Ответ 3

Частное приложение превращает его в свойство readonly. Обычный пример: если у вас есть несколько классов, проходящих вокруг одного объекта, вы не хотите, чтобы другой класс мог модифицировать экземпляр.

Ответ 4

В принципе, это свойство 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 ++;
   }
}

Ответ 5

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

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();
}

Ответ 6

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

Ответ 7

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

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;
    }
}

Ответ 8

Это просто laziness, который возникает из-за свойств auto. До того, как были установлены свойства auto, люди будут использовать getter и опустить setter для свойств, предназначенных только для чтения.

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

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

Ответ 9

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

public string Bazinga { get; private set; }

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