属性与方法

快速问答: 什么时候决定使用属性(在 C # 中) ,什么时候决定使用方法?

我们正忙于进行这种辩论,并发现在一些领域,我们是否应该使用属性或方法是有争议的。一个例子是:

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

在本例中,Label是 ASPX 页面上的一个控件。是否有一个原则可以支配决策(在这种情况下) ,使之成为一个方法还是一个属性。

我接受这个最笼统、最全面的答案,但它也涉及到我给出的例子。

69661 次浏览

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

如果您正在执行一些可能影响多个数据成员的复杂操作,则使用方法更为合适。或者,如果 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 中,使用属性还有其他含义:

  • 属性在 Databinding 使用,而 get _/set _ method 不使用。
  • XML 序列化用户属性作为序列化的自然机制。
  • 属性由 < strong > PropertyGrid 控件和实际 < strong > ICUSTomTypeDescriptor 访问,如果编写自定义库,则可以有效地使用它们。
  • 属性由 属性 控制,可以明智地使用它来设计面向方面的软件。

关于物业用途的误解:

  • 用于暴露小的计算: < strong > ControlDesigner. SelectionRules 的 get 块运行到72行! !
  • 用于公开内部数据结构: 即使属性没有映射到内部数据成员,如果它是类的属性,也可以将其用作属性。即使不建议使用 class 属性的属性,也要像返回数据成员一样返回数组(相反,方法用于返回成员的深拷贝)

在这个例子中,它可以被写成,更多的商业意义如下:

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

通过 MSDN 搜索,我在 属性与方法上找到了一个参考资料,它为创建方法提供了一些很好的指南:

  • 操作是一个转换,例如 Object.ToString
  • 操作的开销足以让您想要与 他们应该考虑缓存的用户 结果。
  • 使用 get 访问器获取属性值将具有可观察的 副作用。
  • 连续两次调用该成员会产生不同的结果。
  • 执行的顺序很重要。请注意,类型的属性应该 可以在任何 秩序。
  • 该成员是静态的,但返回一个可以更改的值。
  • 成员返回数组。返回数组的属性可以是 非常具有误导性,通常都是这样 的副本 内部数组,使用户不能 改变内部状态。这,耦合 用户可以很容易地 假设它是一个索引属性, 导致代码效率低下。

我来自 java,我用了一段时间的 get. . set. . method。

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

今天我有一个方法 SetAge (int age)明天我还会有一个方法 SetAge (date born date) ,它使用出生日期来计算年龄。

我对 Get 和 Set 中的编译器转换属性感到非常失望,但是没有考虑我的 Get... 和 Set。.方法相同。

下面是一组很好的 指南,用于说明什么时候使用属性,什么时候使用来自 比尔 · 瓦格纳的方法

  • 当所有这些都成立时使用属性: Getter 应该简单,因此不太可能抛出异常。注意,这意味着没有网络(或数据库)访问。两者都可能失败,因此将引发异常。
  • 它们不应该相互依赖。注意,这将包括设置一个属性并使其影响另一个属性。(例如,设置 FirstName 属性将影响组成名字 + 姓氏属性的只读 FullName 属性,这意味着存在这种依赖关系)
  • 它们应该可以按任何顺序设置
  • Getter 没有可观察到的副作用注意,本指南并不排除属性中某些形式的惰性计算。
  • 该方法必须始终立即返回。(注意,这排除了进行数据库访问调用、 Web 服务调用或其他类似操作的属性)。
  • 如果成员返回数组,则使用方法。
  • 对 getter 的重复调用(没有中间的代码)应该返回相同的值。
  • 对 setter 的重复调用(具有相同的值)应该与单个调用没有区别。

  • Get 不应返回对内部数据结构的引用(参见项目23)。方法可以返回深度副本,并可以避免这个问题。

摘自我对一个重复问题的回答 * 。

属性的另一大优点是在调试期间可以在 VisualStudio 中看到属性的值。

这很简单。

1: 使用属性时,您希望在将数据存储在字段中之前应该验证数据。因此,通过这种方式,属性为字段提供封装。因为如果您离开您的字段,公共最终用户可以分配任何值,这些值可能有效,也可能无效,根据您的业务需求,比如年龄应该大于18岁。所以在值存储对应字段之前,我们需要检查它的有效性。这样,属性表示数据。

2: Use method 当您想执行某些操作时,比如您提供了一些数据作为参数,而您的方法正在根据提供的值执行一些处理,并将处理后的值作为输出返回。或者您希望通过此计算更改某个字段的值。“用这种方法表示行动”。