2009-03-02 64 views
104

快速问题:您何时决定使用属性(在C#中)以及何时决定使用方法?属性vs方法

我们正在忙着进行这场辩论,并且发现了一些我们是否应该使用财产或方法值得商榷的领域。一个例子是这样的:

public void SetLabel(string text) 
{ 
    Label.Text = text; 
} 

在这个例子中,Label是一个ASPX页面上的控件。是否有一个原则可以决定是否将此作为一种方法或一种财产。

我会接受最通用最全面的答案,但这也涉及到我给出的例子。

+2

-1这个问题已经被问及之前回答:http://stackoverflow.com/questions/164527/exposing-member-objects-as-properties-or-methods-in-net – Element 2009-03-02 08:36:46

+0

方法/字段/属性利弊会引起长时间的辩论;一些常用的属性:当你想要私人/受保护的领域,但同时你想暴露他们。另一个用途是不仅有语句,而且还有表达式(如果你喜欢,可以采取行动),即使if()检查(按照MSDN)。但这很棘手,因为用户并不总是知道访问变量(属性)后的处理成本(即代码不可用),并且出于严格的原因必须对该属性进行基准测试。哦,还有一个“奖励”,你不能用属性指针。 – mireazma 2016-11-28 13:14:53

回答

111

从设计准则的开发类库Choosing Between Properties and Methods部分:

一般来说,方法代表操作和性能表现数据。属性意味着像字段一样使用,这意味着属性不应该在计算上复杂或产生副作用。如果它没有违反以下准则,请考虑使用属性而不是方法,因为经验较少的开发人员发现属性更易于使用。

+3

虽然我很同意这一点,但我不认为关于副作用的部分是正确的。例如,“颜色”通常是一个对象的属性,它有明显的副作用(改变对象的颜色)。更改属性具有更改对象状态的明显副作用。 – 2009-03-02 08:48:28

47

是的,如果您所做的只是获取和设置,请使用属性。

如果您正在做一些可能影响多个数据成员的复杂操作,则更合适。或者如果你的getter使用参数,或者你的setter的参数不止一个值。

中间是一条灰色区域,线条可能有点模糊。没有硬性规定,不同的人有时会不同意某种东西是财产还是方法。重要的是要与你的如何做(相对)一致(或者你的团队如何做)。

它们在很大程度上是可以互换的,但是一个属性向用户表明实现相对“简单”。哦,语法更清洁一点。

一般来说,我的理念是,如果您开始编写一个以get或set开头并且分别占用零个或一个参数的方法名称,那么它是属性的主要候选项。

+0

我认为这应该是被接受的答案。 – 2016-05-07 23:13:23

+0

最低票数。这是不正确的。 getter/setter代码的复杂性被封装在getter/setter代码中。它有多复杂,根本不相关,也不会影响多个数据成员。确实,非标准或多个参数需要一种方法,但否则这个答案是不准确的。 – Hal50000 2016-11-10 23:18:05

+0

第一句解释所有。布拉沃。 – SWIIWII 2017-09-23 20:58:41

3

我更喜欢使用属性添加/设置方法与参数。如果参数更多,请使用方法。

3

属性应该只是简单的设置并获得一个衬垫。任何更多,它应该真的被转移到一种方法。复杂的代码应该总是在方法中。

12

如果你正在设置对象的实际属性,那么你使用一个属性。

如果您正在执行任务/功能,那么您可以使用一种方法。

在你的例子中,它是一个确定的属性被设置。

但是,如果您的功能是AppendToLabel,那么您将使用一种方法。

2

属性是非常好的,因为它们可以在Visual Studio的可视化设计器中访问,只要它们可以访问。

他们使用的是你只是设置和获取,也许一些验证,不访问大量的代码。要小心,因为在验证过程中创建复杂对象并不简单。

其他方法是首选的方法。

它不只是关于语义。在视觉工作室视觉设计师中使用不合适的属性开始出现怪异现象。

例如,我在一个类的属性中获取配置值。配置类实际上会打开一个文件并运行一个sql查询来获取该配置的值。这在我的应用程序中导致了问题,即配置文件被Visual Studio本身打开和锁定,而不是我的应用程序,因为它不仅仅是读取,而是写入配置值(通过setter方法)。为了解决这个问题,我只好把它改成一个方法。

3

我只使用变量访问属性,即获取和设置单个变量,或获取和设置控件中的数据。只要需要/执行任何类型的数据操作,我就使用方法。

7

你只需要看看这个名字......“属性”。这是什么意思?字典在很多方面对它进行了定义,但在这种情况下,“一个事物的基本或独特的属性或质量”最适合。

想想行动的目的。事实上,你是否在改变或检索“一个基本或独特的属性”?在你的例子中,你正在使用一个函数来设置一个文本框的属性。这似乎有点愚蠢,不是吗?

属性确实是函数。他们都编译得到XXX()和setXXX()。它只是将它们隐藏在句法糖中,但它为过程提供了语义含义的糖。

想想像属性这样的属性。一辆汽车有很多属性。颜色,MPG,模型等。并非所有的属性都是可封闭的,有些属于可计算的。

同时,一个方法是一个动作。 GetColor应该是一个属性。 GetFile()应该是一个函数。另一个经验法则是,如果它不改变对象的状态,那么它应该是一个函数。例如,CalculatePiToNthDigit(n)应该是一个函数,因为它实际上并不改变它所连接的Math对象的状态。

这可能是漫不经心的,但它确实归结为决定你的对象是什么,以及它们代表什么。如果你不能确定它应该是一个属性还是功能,那么可能哪个不重要。

8

语义属性是对象的属性。 方法是你的对象的行为。

标签是一个属性,使它成为一个属性更有意义。

在面向对象编程方面,您应该清楚地了解什么是行为的一部分,什么是属性。

车{颜色,型号,品牌}

汽车有颜色,型号,因此品牌属性,它没有任何意义有一种方法的setColor或则setModel因为symantically我们不问车设置自己的颜色。

因此,如果您将属性/方法案例映射到真实生活对象或从语义视角查看它,那么您的混淆将会真正消失。

12

属性是一种从对象注入或检索数据的方法。它们创建一个对类中的变量或数据的抽象。它们类似于Java中的getter和setter。

方法封装操作。

在一般情况下,我使用属性来暴露数据的单个位,或类的小计算,如销售税。这是从购物车中的物品数量及其成本中获得的。

我在创建操作时使用方法,如从数据库中检索数据。任何具有移动部件的操作都是方法的候选人。

在您的代码示例中,我将它包装在一个财产,如果我需要访问它之外它含有类:

public Label Title 
{ 
    get{ return titleLabel;} 
    set{ titleLabel = value;} 
} 

设置文本:

Title.Text = "Properties vs Methods"; 

如果我只是设置标签的文本属性这是我该怎么做的:

public string Title 
{ 
    get{ return titleLabel.Text;} 
    set{ titleLabel.Text = value;} 
} 

设置文本:

Title = "Properties vs Methods"; 
2

作为设计属性表示数据或类对象的属性,而方法是类对象的动作或行为。

在.NET中,世界上有使用性质等方面的影响:

  • 属性在数据绑定使用,而的get_/set_方法都没有。
  • XML序列化用户属性作为自然的服务机制。
  • 属性访问PropertyGrid控制和实习生ICustomTypeDescriptor,如果您正在编写自定义库,它可以有效地使用。
  • 属性由Attributes控制,人们可以明智地使用它来设计Aspect Oriented软件。

误解(恕我直言)有关属性用法:

  • 用来揭露小算了一笔账:ControlDesigner.SelectionRules的获取块运行到72行!
  • 用于公开内部数据结构:即使某个属性没有映射到内部数据成员,也可以将其用作属性(如果该属性是您的类的属性)。 Viceversa,即使它的类属性属性不可取,也可以返回类似数据成员的数组(而不是方法用于返回成员的深层副本。)

在这里的例子也可以写成,提供更多的商业意义:

public String Title 
{ 
    set { Label.Text = text; } 
} 
7

通过MSDN搜索,我发现Properties vs Methods提供用于创建方法的一些伟大的准则参考:

  • 该操作是一种转换,如Object.ToString
  • 该操作非常昂贵,您希望与 用户沟通,他们应该考虑高速缓存 的结果。
  • 使用get访问器获取属性值会产生可观察的 副作用。
  • 连续两次调用成员会产生不同的结果。
  • 执行顺序很重要。请注意,可以按任意 的顺序设置和检索类型的属性 。
  • 该成员是静态的,但返回一个可以更改的值。
  • 该成员返回一个数组。返回数组的属性可能是非常容易让人误解的 。通常是 需要返回 内部阵列的副本,以便用户不能更改内部状态 。这与 耦合在一起,事实上用户可以容易地将 假设为索引属性, 导致低效的代码。
-1

我来自java一个我用get .. set ..方法一段时间。

当我编写代码时,我不会问自己:“访问这些数据很简单,还是需要一个繁重的过程?” 因为事情可以改变(今天回顾这个属性很简单,tomonrow可能需要一些或繁重的过程)。

今天我有一个方法SetAge(int age)tomonrow我也会用方法SetAge(date birthdate)来计算使用出生日期的年龄。

我很失望,编译器在get和set中转换属性,但不认为我的Get ...和Set ..方法是一样的。

-1

这里是一个很好一套指引何时使用性能相方法从Bill Wagner

  • 使用一个属性当所有这些都是真的: 的干将应该是简单的,因此不太可能抛出异常。请注意,这意味着没有网络(或数据库)访问。要么可能会失败,因此会抛出异常。
  • 他们不应该彼此依赖。请注意,这将包括设置一个属性并影响另一个属性。(例如,设置了名字属性将影响由第一名+姓性质隐含了这种相关性的只读FullName属性)
  • 他们应该以任何顺序
  • 吸气不具有可观察到的是设定副作用请注意,本指南并不排除某种形式的物业惰性评估。
  • 该方法必须始终立即返回。 (请注意,这排除了进行数据库访问调用,Web服务调用或其他类似操作的属性)。
  • 如果成员返回数组,则使用方法。
  • 重复调用getter(无中介代码)应返回相同的值。
  • 重复调用setter(具有相同的值)的调用应该不会影响单个调用。

  • get不应该返回对内部数据结构的引用(请参阅第23项)。一种方法可以返回一个深层副本,并可以避免这个问题。

*从我的答案采取重复问题。

3

属性的另一大优点是在调试过程中可以在Visual Studio中看到属性的值。