为什么我们使用.NET属性而不是普通的旧get/set函数?

Dan*_*Tao 17 .net oop properties

我理解提供一个间接访问类成员的接口的好处.我的问题是:并不是你已经可以用任何OO语言完成的东西(有些东西)

public int NormalClass::getQuality() {
    return this->quality;
}
Run Code Online (Sandbox Code Playgroud)

protected void NormalClass::setQuality(int q) {
    this->quality = q;
}
Run Code Online (Sandbox Code Playgroud)

除了纯粹的美学外,.NET属性还提供了哪些额外的好处?

如果你能为它做出令人信服的论证,我会接受"可读性"; 但就个人而言,我倾向于认为get/set函数比属性更具可读性,因为它明确地是一个函数而不是一个直接值.

编辑:感谢大家的回答!这对我来说真的很有用; 总结一下我从所有人那里收集/学到的东西,以下是我到目前为止得出的一些结论:

  • 属性的最大好处不是来自属性本身的特定功能,而是来自以特殊方式处理属性的框架和IDE功能; 例如,属性编辑器,XML序列化,数据绑定.
  • 可以通过某些方便的方式将属性视为简单值,get/set函数不能:特别是obj.Prop ++和obj.Prop = value.
  • 使用属性可以让您使用公共成员快速而肮脏的代码,而不必担心以后实现一堆get/set函数; 如果您需要添加一些逻辑和/或将公共成员设为私有,您可以简单地引入一个属性,而不是冒险破坏任何旧代码.

现在,到目前为止,有两点已经在2或3个答案中做出,我个人觉得有点可疑:这些属性意味着廉价的读/写操作,因此可以与简单变量基本相同的方式使用.我关于这一点的问题是,实际上强制执行此操作的属性中没有固有的东西; 这只是他们如何应该使用.对我来说,这是类似于一个"shouldBePrivate"限定符指示值应该只由它自己的类直接访问,但仍然可以从外部访问无论如何; 还是在街上巡逻的警察部队提醒我们,我们应该表现自己,但在我们开始犯罪时实际上并没有干涉(如果没有强制执行,它对我们真正做了什么?).

如果属性具有某种内置机制来确保读/写便宜,我会对这一点印象更深刻.

LBu*_*kin 24

Jon Skeet对他的C#文章博客有一个很好的概述,关于为什么属性很重要.在其中,他解释了为什么应该使用属性来暴露公共领域.

至于为什么要使用属性而不是getter/setter方法,我建议以下想法:

  • 属性提供了更简洁,更简洁的语法,易于理解和阅读.
  • 属性启用赋值表达式链接: A.x = B.y = C.z
  • 属性清晰一致地传达数据访问的语义 - 消费者期望没有副作用.
  • .NET中的许多库都可以识别属性,例如XML序列化,WPF绑定,ASP.NET双向绑定等任务.
  • 属性可由IDE和许多可视化设计人员识别,并可在属性编辑器中显示.
  • 属性启用对增量(++)和减量( - )运算符的支持.
  • 可以使用反射方法轻松区分属性,并允许动态使用者提取有关对象公开的数据的知识.
  • C#3支持自动属性,有助于消除样板代码.

  • 哇,即使Jon Skeet没有回答这个问题,Jon Skeet正在回答这个问题:) (5认同)
  • 不只是++和 - ,还有修饰赋值运算符,如+ =,*=,| =等. (4认同)

Edu*_*coz 13

属性(.net 3.5中的特殊自动属性)比setter/getter更简洁,代码行数少= =维护代码少= =更少错误.

我会先说可读性,但你已经说过不会算你... :)


Cod*_*nis 10

我相信XML Serialization只读取/写入公共属性,因此您的get和set方法将被忽略.

此外,如果您有一个通用的对象列表,您可以将其分配给DataGridView.DataSource,您将获得每个属性的列.这可能是@LPalmer所指的.


usr*_*usr 7

不仅在语言中而且在clr中具有属性意味着.NET上的每个人都可以依赖于他们的元数据.属性具有无副作用的内涵,并且get和set都是快速操作.许多工具使用这些假设:winforms设计器,LINQ to SQL ......

因此,它不仅仅是为了方便而且还有一个额外的元数据.

以下是其他典型假设:

customer.Name = "a";
Assert.IsTrue(customer.Name == "a");

try { var ignored = customer.Name; }
catch { Assert.Fail("Exceptions are not expected"); }
Run Code Online (Sandbox Code Playgroud)