Опущенный сеттер против частного сеттера?

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

public string Foo { get; private set; }

vs

public string Foo { get; }

5 ответов


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

свойство с private set; можно установить отовсюду внутри этого класса.


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

public string Foo { get; }

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

public string Foo { get; private set; }

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

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

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, но не C#, что означает, что вы никогда не сможете напишите код C#, который будет конфликтовать с таким автоматически сгенерированным членом.

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

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

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

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, не только само свойство не доступно для записи, но и поле поддержки также readonly означает, что теперь вы лучше оснащены, чтобы легко писать неизменяемые типы.


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

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


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

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