省略 setter 与私有 setter?
Omitted setter vs private setter?
省略 setter 的 属性 和带有私有 setter 的 属性 有什么区别?
public string Foo { get; private set; }
对
public string Foo { get; }
在 class 之外,如果您使用此语法,它不会改变任何内容:
public string Foo { get; }
但是您将无法在 class 中更新 Foo
,除了在构造函数中,要这样做,您需要私有 setter:
public string Foo { get; private set; }
在 C# 6 中,get;
只有属性只能从构造函数中设置。在其他任何地方,它都是只读的。
带有 private set;
的 属性 可以从 class.
中的任何地方设置
省略了 setter 的 属性 在除 class 构造函数之外的任何地方都是只读的 - 包括 class.
内部
具有私有 setter 的 属性 只能在外部读取(甚至对子classes),但在内部可写。
private
setter 是 - 嗯 - 一种私有设置方法,您只能在 class 内部使用。
省略setter使属性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 但不是 C#,这意味着您永远不能编写会与此类自动生成的成员冲突的 C# 代码。
基本上,C# 中的自动属性只是带有支持字段的 属性 的语法糖,实际编译的 属性 仍然有一个支持字段,您只是不必编写它明确。
如您所见,它还自动重写了构造函数以直接写入字段。请注意,这将在写入 class 的任何地方完成,因为任何自定义代码都不可能介于两者之间。
现在让我们从 属性 中删除 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; }
}
}
请注意,该字段现在是只读的,显然 setter 也从 属性 中消失了。
所以这实际上是现在创建具有 true 只读属性的简单类型的最佳方法,不仅 属性 本身不可写,而且支持字段是也是只读的,这意味着您现在可以更好地轻松编写 不可变类型 .
省略 setter 的 属性 和带有私有 setter 的 属性 有什么区别?
public string Foo { get; private set; }
对
public string Foo { get; }
在 class 之外,如果您使用此语法,它不会改变任何内容:
public string Foo { get; }
但是您将无法在 class 中更新 Foo
,除了在构造函数中,要这样做,您需要私有 setter:
public string Foo { get; private set; }
在 C# 6 中,get;
只有属性只能从构造函数中设置。在其他任何地方,它都是只读的。
带有 private set;
的 属性 可以从 class.
省略了 setter 的 属性 在除 class 构造函数之外的任何地方都是只读的 - 包括 class.
内部具有私有 setter 的 属性 只能在外部读取(甚至对子classes),但在内部可写。
private
setter 是 - 嗯 - 一种私有设置方法,您只能在 class 内部使用。
省略setter使属性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 但不是 C#,这意味着您永远不能编写会与此类自动生成的成员冲突的 C# 代码。
基本上,C# 中的自动属性只是带有支持字段的 属性 的语法糖,实际编译的 属性 仍然有一个支持字段,您只是不必编写它明确。
如您所见,它还自动重写了构造函数以直接写入字段。请注意,这将在写入 class 的任何地方完成,因为任何自定义代码都不可能介于两者之间。
现在让我们从 属性 中删除 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; }
}
}
请注意,该字段现在是只读的,显然 setter 也从 属性 中消失了。
所以这实际上是现在创建具有 true 只读属性的简单类型的最佳方法,不仅 属性 本身不可写,而且支持字段是也是只读的,这意味着您现在可以更好地轻松编写 不可变类型 .