Не указано setter vs private setter?

В чем разница между свойством с пропущенным сеттером и свойством с приватным сетевым устройством?

public string Foo { get; private set; }

против

public string Foo { get; }

Ответ 1

В С# 6, get; только свойства устанавливаются только из конструктора. С другой стороны, он доступен только для чтения.

Свойство с private set; может быть установлено изнутри внутри этого класса.

Ответ 2

Извне класса это ничего не изменит, если вы используете этот синтаксис:

public string Foo { get; }

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

public string Foo { get; private set; }

Ответ 3

Отличие состоит в том, что сгенерированный код будет генерировать поле readonly во втором случае, и, очевидно, свойство не будет иметь setter.

Сделайте реальный пример:

public class Test
{
    public Test(string name) { Name = name; }
    public string Name { get; private set; }
}

Компилятор выполнит следующее:

public class Test
{
    private string <Name>k__BackingField;
    public Test(string name)
    {
        <Name>k__BackingField = name;
    }
    public string Name
    {
        get { return <Name>k__BackingField; }
        private set { <Name>k__BackingField = value; }
    }
}

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

В принципе, автоматические свойства в С# являются просто синтаксическим сахаром для свойства с полем поддержки, у самого скомпилированного свойства все еще есть поле поддержки, вам просто не нужно его явно писать.

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

Теперь удалите установщик из свойства и посмотрим, что произойдет:

public class Test
{
    private readonly string <Name>k__BackingField;
    public Test(string name)
    {
        <Name>k__BackingField = name;
    }
    public string Name
    {
        get { return <Name>k__BackingField; }
    }
}

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

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

Ответ 4

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

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

Ответ 5

Установитель private - это - метод приватного набора, который вы можете использовать только внутри вашего класса.

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