All*_*hua 60 c# readonly private-members
我一直在努力创建一个课程,突然想到了两个代码之间有什么区别:
public readonly string ProductLocation;
Run Code Online (Sandbox Code Playgroud)
和
public string ProductLocation
{
get;
private set;
}
Run Code Online (Sandbox Code Playgroud)
你能告诉我什么时候更好地使用以下内容吗?谢谢.
Bru*_*eis 79
第一个是只读字段,而第二个被编译为一对方法(并且属性的所有读取都ProductLocation
被编译为对相应get
方法的调用,并且写入它被编译为对set
方法的调用;在内部,这些方法将读取/写入内部的,自动生成的非只读字段.我说最重要的区别是线程安全!(怎么样?继续阅读!)
该类的基本用法看起来完全相同:其他类中的代码只能读取值,而不能更改它.此外,读取值的代码看起来完全相同(例如,print(myInstace.ProductLocation)
;在这里,你不能告诉它是如何被声明的,很酷,是吗?)
第一个,最微不足道的区别是具有私有setter的属性允许同一个类的实例修改该值,而在readonly属性的情况下,甚至对象本身都不能更改该值.
现在,为线程安全.readonly
当您使用多个线程时,该字段的属性将更改其内存可见性语义(就像Java的final
字段一样).
一个readonly
字段只能在声明或在构造函数中分配.分配给readonly
字段的值不能更改(至少不能以正常方式更改),并且保证每个线程在构造函数返回后都会看到正确的初始化值.因此,readonly
字段本质上是线程安全的.
要使用属性实现相同的线程安全性,您必须在代码上添加一些同步,这很容易出错.根据具体情况,它可能导致死锁,数据竞争或性能降低,特别是如果您没有经验.
因此,如果值表示在对象构造之后在语义上无法更改的值,则不应声明私有setter(这意味着对象可能会更改它).去readonly字段(并且可能声明它是私有的并声明一个只有getter访问字段的公共属性!这实际上是首选形式,因为暴露字段不好,最好只暴露方法 - 那里有很多理由解释为什么在这个答案中)
str*_*ius 23
使用C#6.0 自动属性初始化程序,可以减少样板操作
private readonly string productLocation;
public string ProductLocation { get { return productLocation; } }
Run Code Online (Sandbox Code Playgroud)
这是
public string ProductLocation { get; }
Run Code Online (Sandbox Code Playgroud)
这是只读的.仅从构造函数或内联初始化.初始化后无法编辑.(从任何地方都可以)
但是,如果你使用私人套装;
public string ProductLocation { get; private set }
Run Code Online (Sandbox Code Playgroud)
这是从外面读取的.但是可以在类本身的任何地方随时初始化.并且可以通过类本身在其生命周期内进行编辑.(从课堂变化,从外部不变)
Ant*_*ram 18
通常,.NET不鼓励公开公开成员字段,这些字段应该由属性包装.所以我们假设你可能有
private readonly string productLocation;
public string ProductLocation { get { return productLocation; } }
Run Code Online (Sandbox Code Playgroud)
VS
public string ProductLocation { get; private set; }
Run Code Online (Sandbox Code Playgroud)
在这种设置中,忽略了人们可以通过反射完成的事情,语义是在第一种情况下,productLocation
变量只能在适当的位置和类构造函数中初始化.班上的其他成员不能改变价值.外部消费者无法设定价值.
在第二个版本中,外部消费者继续无法设置价值.但是,类本身可以随时更改值.如果你拥有的只是一个DTO(也就是说,一个只传输数据的类,它没有通过方法表达的逻辑),那么这与readonly
版本完全不同.但是,对于具有方法的类,这些方法可能会改变背后的价值ProductLocation
.
如果要在构造后强制执行不可变字段的概念,请使用readonly
.但对于DTO,我可能会private set;
选择,主要是因为它的样板代码较少.
第一个(使用readonly
)将意味着一旦对象被实例化,对象甚至不能修改它自己的字段的值,而其他对象永远不能修改它.
第二个(使用private set
)将意味着对象可以在实例化后修改其字段的值,但其他人永远不能修改它.
我会将前者用于你知道不会改变的东西,并将后者用于价值可能改变的东西,但你不希望别人改变它.
归档时间: |
|
查看次数: |
13621 次 |
最近记录: |