Getter and Setter declaration in .NET
我想知道getter和setter声明之间的区别是什么,以及是否存在首选方法(以及为什么)。第一个可以由Visual Studio自动生成。其他人呢?谢谢
第一
1 | string _myProperty { get; set; } |
第二
1 2 3 4 5 6 7 | string _myProperty; public string myProperty { get { return _myProperty; } set { _myProperty = value; } } |
第三
1 2 3 4 5 6 7 8 9 10 11 | string _myProperty; public string getMyProperty() { return this._myProperty; } public void setMyProperty(string value) { this._myProperty = value; } |
属性用于封装某些数据。您可以使用普通字段:
1 | public string MyField |
但是这个字段可以被类的所有外部用户访问。人们可以插入非法值或以您不期望的方式更改值。
通过使用属性,可以封装数据的访问方式。C有一个很好的语法,可以将字段转换为属性:
1 | string MyProperty { get; set; } |
这称为自动实现的属性。当需要时,您可以将您的财产扩展到:
1 2 3 4 5 6 7 | string _myProperty; public string MyProperty { get { return _myProperty; } set { _myProperty = value; } } |
现在,您可以添加验证
1 2 3 4 5 6 7 | set { if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(); _myProperty = value; } |
属性还可以为getter和setter使用不同的访问器:
1 | public string MyProperty { get; private set; } |
这样,您就创建了一个属性,每个人都可以读取它,但只能由类本身修改它。
您还可以为您的
1 2 3 4 5 6 7 | public string MyProperty { get { return DateTime.Now.Second.ToString(); } } |
当C编译自动实现的属性时,它会生成中间语言(IL)。在您的IL中,您将看到一个
按照惯例,对于需要很长时间的操作,不应该使用属性。
好吧,第一个和第二个都会产生类似于第三个的结果。但是,当您有属性语法时,不要使用第三个。
最后,如果您在
最后,第一个和第二个只是某种形式的句法糖分,但为什么代码比必要的要多。
1 | // more code == more bugs |
为了好玩,考虑一下:
1 | public string A { get; private set; } |
现在说得更直接了,不是吗?
第一
1 | string _myProperty { get; set; } |
这在.NET世界中被称为自动属性。它只是2的句法糖。
第二
1 2 3 4 5 6 7 | string _myProperty; public string myProperty { get { return _myProperty; } set { _myProperty = value; } } |
这是通常的方法,如果您需要在您的属性中进行任何验证或额外的代码,就需要这样做。例如,在WPF中,如果需要触发属性更改事件。如果不这样做,只需使用auto属性,它就相当标准了。
三
1 2 3 4 5 6 7 8 9 10 11 | string _myProperty; public string getMyProperty() { return this._myProperty; } public string setMyProperty(string value) { this._myProperty = value; } |
这里的
这样,您就可以在
1 2 3 4 5 6 | private string _myProperty; public string myProperty { get { return _myProperty; } set { _myProperty = value; } } |
您还可以使用自动属性:
1 2 3 4 5 | public string myProperty { get; set; } |
NET框架将为您管理。它之所以被创造,是因为它是一个很好的实践,而且很容易做到。
您还可以控制这些范围的可见性,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public string myProperty { get; private set; } public string myProperty2 { get; protected set; } public string myProperty3 { get; } |
更新
现在在C中,您可以初始化属性的值。样品:
1 | public int Property { get; set; } = 1; |
如果也可以定义它并使其成为只读的,而不需要设置。
1 | public int Property { get; } = 1; |
最后,您可以定义一个箭头函数。
1 | public int Property { get; } => GetValue(); |
只是澄清一下,在第三个示例中,myproperty实际上不是一个属性。这是一个包含get和set方法的字段(正如前面提到的,get和set方法应该指定返回类型)。
在大多数情况下,应避免使用第三种方法。如果要返回的类型是数组,或者get方法做了很多工作,而不仅仅是返回一个值,那么只需要使用它。后者并非真正必要,但为了清晰起见,执行大量工作的属性的get方法具有误导性。
让我们从3开始。那是行不通的。
数字1和2实际上是一样的。2是编译后的数字1。
所以1和2是一样的。有了两个,您可以在模型中进行一些验证或缓存。
除此之外,它们变得相同。
第一个是"短"形式——当你不想对你的getter和setter做一些花哨的事情时,你就使用它。不可能以这种形式执行方法或类似的东西。
第二种和第三种形式几乎相同,尽管第二种形式被压缩成一行。StyleCop不鼓励这种形式,因为它看起来有点奇怪,不符合C'StyleGuides。
如果我希望使用getter/setter来处理一些特殊的事情,比如使用懒惰的结构,我会使用第三种形式。
第一个是默认值,当没有特殊的返回或写入时。第二个和第三个基本相同,其中第三个是第二个扩展版本