В чем разница между свойством с пропущенным сеттером и свойством с приватным сетевым устройством?
public string Foo { get; private set; }
против
public string Foo { get; }
В чем разница между свойством с пропущенным сеттером и свойством с приватным сетевым устройством?
public string Foo { get; private set; }
против
public string Foo { get; }
В С# 6, get;
только свойства устанавливаются только из конструктора. С другой стороны, он доступен только для чтения.
Свойство с private set;
может быть установлено изнутри внутри этого класса.
Извне класса это ничего не изменит, если вы используете этот синтаксис:
public string Foo { get; }
Но вы не сможете обновить Foo
внутри класса, за исключением конструктора, для этого вам понадобится частный сеттер:
public string Foo { get; private set; }
Отличие состоит в том, что сгенерированный код будет генерировать поле 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, а не только само свойство не доступно для записи, но поле резервного копирования также означает, что теперь вы лучше подготовлены к тому, чтобы легко писать неизменяемые типы.
Свойство с пропущенным сеттером читается только везде, кроме конструктора класса - включая внутри класса.
Свойство с частным сеттером читается только извне (даже в подклассы), но записывается внутри.
Установитель private
- это - метод приватного набора, который вы можете использовать только внутри вашего класса.
Пропущенный сеттер делает свойство readonly
. Таким образом, вы можете установить значение этого свойства только в своем конструкторе или с помощью статической инициализации.