省略二传手vs私人二传手?

省略二传手vs私人二传手?

问题描述:

一个遗漏的二传手财产和一个私人二传手财产之间的区别是什么?省略二传手vs私人二传手?

public string Foo { get; private set; } 

VS

public string Foo { get; } 
+5

简单:一个遗漏setter **的属性没有setter **。您不能在属性声明或构造函数之外重新分配属性。 – BoltClock

+3

这个问题怎么来得到提升?我认为这是微不足道的... – Alex

+3

重复提醒:http://*.com/questions/3847832/understanding-private-setters,http://*.com/questions/4948816/getters-setters-and-properties-最佳做法-java-vs -c-sharp – Tushar

在C#6中,get;只有属性只能从构造函数中设置。从其他地方,它是只读的。

一个private set;属性可以从该类中的任何地方设置。

+0

我明白了。我想知道为什么功能存在遗漏setter。声明一个只能由构造函数设置的属性,或者通过类内部的方法声明一个属性的原因是什么? – Fred

+0

为防止在该方法内部错误地设置该属性? –

从类外,如果使用此语法它不会改变任何东西:

public string Foo { get; } 

但你不能内更新Foo除了在构造函数中,类需要这样做,您需要私有设置器:

public string Foo { get; private set; } 
+1

*你将无法在课堂内更新Foo *错误。你只能在构造函数中设置它。 –

+0

@PatrickHofman感谢您的评论,我以前不知道! –

+0

有趣的是,每个答案都有这个特定的部分错了,仍然得到了投票,而我的指出,从一开始,并没有得到任何投票... –

具有省略setter的属性只能在类构造函数(包括类内部)中读取。

具有私有setter的属性只能从外部读取(即使是子类),但在内部可写。

private setter是 - 好 - 一个私人设置的方法,你只能在你的课堂内使用。

省略 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#自动属性仅仅是一个支持字段属性语法糖,被编译的实际属性仍然有支持字段,你只是没有把它明确写入。

正如你可以看到它还会自动改写构造函数直接写入到外地。请注意,这将在该类中写入属性的任何地方完成,因为无论如何都不可能有任何自定义代码。

现在让我们从属性中删除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; } 
    } 
} 

注意,字段现在只读,并再次,显然制定者已经从财产了为好。

所以实际上现在与真正只读属性创建简单类型的最佳方式,不光是属性本身不可写,但支持字段也是只读意味着你现在更好的装备,轻松地编写不可变类型

+0

有趣的是,我想这也适用于静态只读属性(即当它只声明一个自动获取) –

+0

是的,'静态'在这方面并不重要 –

+0

我没有试图看看发生了什么在这种情况下(无论是实例还是私有属性都只有'get;')。因此,我不会手动声明更多'readonly'字段; P(除非我不需要封装它们,但是在没有封装的情况下访问类字段仍然是一种错误的编码习惯)。 –