具有省略的setter的属性与具有私有setter的属性之间有什么区别?
public string Foo { get; private set; }
VS
public string Foo { get; }
答案 0 :(得分:42)
在C#6中,get;
只能从构造函数中设置属性。从其他地方来看,它是只读的。
可以从该类中的任何位置设置具有private set;
的属性。
答案 1 :(得分:10)
如果你使用这种语法,从课堂外面来看,它不会改变任何东西:
public string Foo { get; }
但是,除了在构造函数中,您无法在类中更新Foo
,这样做,您需要私有的setter:
public string Foo { get; private set; }
答案 2 :(得分:6)
不同之处在于,生成的代码将在第二种情况下生成只读字段,显然该属性不会有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而不是C#,这意味着您永远不会编写与此类自动生成的成员冲突的C#代码。
基本上,C#中的自动属性只是具有支持字段的属性的语法糖,正在编译的实际属性仍然有一个支持字段,您只需要不必明确地写它。
正如您所看到的,它还会自动重写构造函数以直接写入字段。请注意,这将在写入属性的此类中的任何位置执行,因为无论如何都不会有任何自定义代码。
现在让我们从属性中删除setter,看看会发生什么:
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,而且很明显,setter也已经离开了该属性。
所以这实际上是现在用 true readonly属性创建简单类型的最好方法,不仅属性本身不可写,而且后备字段也是readonly意味着你现在装备更好轻松编写不可变类型。
答案 3 :(得分:4)
private
setter是 - 嗯 - 您可以在课堂内使用的私人套装方法。
省略 setter使属性readonly
成为可能。因此,您只能在构造函数中或通过静态初始化设置此属性的值。
答案 4 :(得分:3)
具有省略的setter的属性只读取除类构造函数之外的所有位置 - 包括类内部。
具有私有setter的属性只能在外部读取(甚至是子类),但在内部可写。