快速问答: 什么时候决定使用属性(在 C # 中) ,什么时候决定使用方法?
我们正忙于进行这种辩论,并发现在一些领域,我们是否应该使用属性或方法是有争议的。一个例子是:
public void SetLabel(string text) { Label.Text = text; }
在本例中,Label是 ASPX 页面上的一个控件。是否有一个原则可以支配决策(在这种情况下) ,使之成为一个方法还是一个属性。
Label
我接受这个最笼统、最全面的答案,但它也涉及到我给出的例子。
是的,如果您所做的只是获取和设置,那么使用属性。
如果您正在执行一些可能影响多个数据成员的复杂操作,则使用方法更为合适。或者,如果 getter 接受参数,或者 setter 接受的参数超过 value 参数。
中间是一个灰色区域,这里的界限可能有点模糊。没有硬性规定,不同的人有时会不同意某些东西应该是属性还是方法。重要的是要(相对地)与 你是如何做到的(或者你的团队是如何做到的)保持一致。
它们在很大程度上是可互换的,但属性向用户发出信号,表明实现相对“简单”。语法更简洁。
一般来说,我的理念是,如果您开始编写一个以 get 或 set 开头并接受零或一个参数(分别)的方法名,那么它就是属性的主要候选方法。
我更喜欢对带有 1参数的 add/set 方法使用属性。
属性只应该是简单的设置,并获得一行。如果有更多的内容,那么它应该被移动到一个方法中。复杂代码应该始终位于方法中。
如果要设置对象的实际属性,则使用属性。
如果您正在执行一个任务/功能,那么您使用一个方法。
在您的示例中,设置的是一个确定的属性。
但是,如果您的功能是 AppendToLabel,那么您将使用一个方法。
属性非常好,因为它们可以在视觉工作室的可视化设计器中访问,只要它们可以访问。
如果您仅仅是设置和获取,或许还有一些不能访问大量代码的验证,则可以使用它们。要小心,因为在验证期间创建复杂对象并不简单。
任何其他方法都是首选的方法。
这不仅仅是语义学的问题,使用不恰当的属性会使视觉工作室的视觉设计师产生奇怪的感觉。
例如,我在一个类的属性中获取一个配置值。配置类实际上打开一个文件并运行一个 sql 查询来获取该配置的值。这在我的应用程序中引起了一些问题,在这些问题中,配置文件会被 Visual Studio 本身而不是我的应用程序打开和锁定,因为这不仅是读取配置值,而且是写入配置值(通过 setter 方法)。为了解决这个问题,我只需要将它改为一个方法。
从 在属性和方法之间选择的设计指南为开发类图书馆部分:
通常,方法表示操作,属性表示数据。属性应该像字段一样使用,这意味着属性不应该在计算上复杂或产生副作用。如果没有违反以下准则,可以考虑使用属性,而不是方法,因为经验不足的开发人员会发现属性更容易使用。
我只对变量访问使用属性,例如获取和设置单个变量,或者获取和设置控件中的数据。一旦需要/执行任何类型的数据操作,我就使用方法。
你只需要看看这个名字... “财产”。这是什么意思?字典对它的定义有很多种,但在这种情况下,“一个事物的本质或独特的属性或品质”是最合适的。
想想行动的目的。事实上,你是否在改变或检索“一个基本的或独特的属性”?在您的示例中,您正在使用一个函数来设置文本框的属性。听起来有点傻,不是吗?
属性实际上是函数。它们都可以编译成 getXXX ()和 setXXX ()。它只是把它们隐藏在语法 Sugar 中,但是 Sugar 为这个过程提供了一个语义意义。
考虑属性这样的属性。汽车有很多特性。颜色,MPG,型号等。并非所有属性都是可设置的,有些属性是可计算的。
同时,方法是一个操作。GetColor 应该是一个属性。GetFile ()应该是一个函数。另一个经验法则是,如果它不改变对象的状态,那么它应该是一个函数。例如,CalculatePiToNthDigit (n)应该是一个函数,因为它实际上并没有改变它所附加的 Math 对象的状态。
这可能有点漫无边际,但归根结底,它确实决定了您的对象是什么,以及它们代表什么。如果您不能确定它应该是属性还是函数,也许哪个并不重要。
语义属性是对象的属性。 方法是对象的行为。
Label 是一个属性,将其设置为属性更有意义。
在面向对象编程方面,您应该清楚地了解什么是行为的一部分,什么仅仅是一个属性。
汽车{颜色,型号,品牌}
汽车有 Color、 Model 和 Brand 属性,因此使用 SetColor 或 SetModel 方法是没有意义的,因为在语义上我们不要求 Car 设置自己的颜色。
因此,如果您将属性/方法用例映射到现实生活中的对象,或者从语义的角度来看待它,那么您的困惑将真正消失。
属性是从对象注入或检索数据的一种方法。它们在类中创建变量或数据的抽象。它们类似于 Java 中的 getter 和 setter。
方法封装一个操作。
通常,我使用属性来公开单个数据位,或类上的小型计算,如销售税。它是根据购物车中的商品数量及其成本得出的。
我在创建操作时使用方法,比如从数据库中检索数据。任何有活动部件的操作都是方法的候选者。
在您的代码示例中,如果需要访问包含类之外的属性,我会将其包装在一个属性中:
public Label Title { get{ return titleLabel;} set{ titleLabel = value;} }
设定案文:
Title.Text = "Properties vs Methods";
如果我只是设置标签的 Text 属性,我会这样做:
public string Title { get{ return titleLabel.Text;} set{ titleLabel.Text = value;} }
Title = "Properties vs Methods";
属性表示类对象的数据或属性,而方法表示类对象的操作或行为。
在.Net 中,使用属性还有其他含义:
关于物业用途的误解:
在这个例子中,它可以被写成,更多的商业意义如下:
public String Title { set { Label.Text = text; } }
通过 MSDN 搜索,我在 属性与方法上找到了一个参考资料,它为创建方法提供了一些很好的指南:
操作是一个转换,例如 Object.ToString。 操作的开销足以让您想要与 他们应该考虑缓存的用户 结果。 使用 get 访问器获取属性值将具有可观察的 副作用。 连续两次调用该成员会产生不同的结果。 执行的顺序很重要。请注意,类型的属性应该 可以在任何 秩序。 该成员是静态的,但返回一个可以更改的值。 成员返回数组。返回数组的属性可以是 非常具有误导性,通常都是这样 的副本 内部数组,使用户不能 改变内部状态。这,耦合 用户可以很容易地 假设它是一个索引属性, 导致代码效率低下。
Object.ToString
我来自 java,我用了一段时间的 get. . set. . method。
当我编写代码时,我不会问自己: “访问这些数据是简单的还是需要一个繁重的过程?”因为事情可以改变(今天检索这个属性很简单,明天可能需要一些或者繁重的处理)。
今天我有一个方法 SetAge (int age)明天我还会有一个方法 SetAge (date born date) ,它使用出生日期来计算年龄。
我对 Get 和 Set 中的编译器转换属性感到非常失望,但是没有考虑我的 Get... 和 Set。.方法相同。
下面是一组很好的 指南,用于说明什么时候使用属性,什么时候使用来自 比尔 · 瓦格纳的方法
对 setter 的重复调用(具有相同的值)应该与单个调用没有区别。
Get 不应返回对内部数据结构的引用(参见项目23)。方法可以返回深度副本,并可以避免这个问题。
摘自我对一个重复问题的回答 * 。
属性的另一大优点是在调试期间可以在 VisualStudio 中看到属性的值。
这很简单。
1: 使用属性时,您希望在将数据存储在字段中之前应该验证数据。因此,通过这种方式,属性为字段提供封装。因为如果您离开您的字段,公共最终用户可以分配任何值,这些值可能有效,也可能无效,根据您的业务需求,比如年龄应该大于18岁。所以在值存储对应字段之前,我们需要检查它的有效性。这样,属性表示数据。
2: Use method 当您想执行某些操作时,比如您提供了一些数据作为参数,而您的方法正在根据提供的值执行一些处理,并将处理后的值作为输出返回。或者您希望通过此计算更改某个字段的值。“用这种方法表示行动”。