属性和方法的区别

16

在返回值的情况下,哪一种更好?

public int EmployeeAge
{
    get{return intEmployeeAge};
}

而且

public int EmployeeAge()
{
    return intEmployeeAge;
}
哪个更好,为什么?在像上面这样的场景中使用最佳编程实践是什么?
8个回答

36

属性是表示对象特征的一种有用方式,允许使用诸如数据绑定、反射和序列化等API共同使用get/set。因此,对于对象的简单值而言,属性非常方便。属性不能带有参数,不应具有重大的副作用*,并且应快速且可重复地返回。另外,不存在“扩展属性”(以反映扩展方法)或通用属性。

(*=懒加载等不常见情况除外)

方法(C#没有函数)更适合表示改变状态的内容,或者其期望需要花费一些时间并且不一定能够复现的内容。它们通常无法在绑定/序列化等方面使用。

请注意,属性实际上只是编写方法的一种特殊方式。在功能上几乎没有区别。这完全取决于表达意图。然而,您不想公开的一件事是字段(实际的intEmployeeAge实例变量)。

所以我会这样做:

public int EmployeeAge { get{return intEmployeeAge}; }

或者只需在Employee对象上执行以下操作:

public int Age { get{return intEmployeeAge}; }

当然...那问题就变成了“以什么单位计算?” 我假设是年?


同意。简单来说,属性的设计是为了将类内部的私有字段暴露给外部,以确保在类架构被修改时不会产生破坏性的变化。 - JoeBilly
@JoeBilly - 嗯,你可以做得更多,而不会变得太混乱。但是简单就是简单,所以他们说。 - Marc Gravell
当然它被推广了。我的意思是,你可以用一个属性做很多事情(好的或者坏的),但它首先是一个访问器。 - JoeBilly
来自Java的角度看,C#属性似乎像是变异器和访问器方法。这个假设正确吗?如果是这样,那么在C#中使用方法获取实例变量是否有意义,因为属性已经可以实现了呢?如果我错了,请纠正我! - Ben Sewards
2
@Ben,你是正确的。而且 get / set 是方法。在幕后,实际上是 get_Ageget_EmployeeAge - Marc Gravell

9

如果你只需要返回一个值,使用属性。

如果在返回值之前需要执行某些操作,请使用函数。


1
但是在属性的情况下,我也可以在返回值之前添加一些处理,你可以称之为“做某事”,在上述情况下两者都返回值。但哪个更好呢? - Asim Sajjad
可以,但你需要考虑“含义”。大多数程序员在调用属性时并不希望改变对象状态,但在调用函数时他们确实期望如此。 - Oded

5

2
哪个更好?为什么?当我们遇到上述情况时,最佳编程实践是什么?我使用C#编写代码,但我更喜欢使用Get/Set函数。对我来说,这是表达从对象中获取什么以及如何改变其状态的更好方式(而且这些方法在Intelisense中按字母顺序分组,这也很不错)。然而,如果团队更喜欢其他约定,那也不是问题。但是当我处理自己的项目时,阅读API更容易。
e.g

Obejct1 o = new Object1();
o.P1;
o.P2;
o.P3;

从API中无法判断你能否对公共API进行更改或它是否是只读属性,除非你使用显示可行操作的小图标的IDE。

Object1 o = new Object1();
o.GetP1();
o.SetP2();
o.SetP3();

通过API,可以轻松地找到数据如何被类型的客户端更改。


1

一个方法在完成工作后返回值,而值是完成工作的结果。我认为这不是你正在做的事情。

属性(访问器)用于返回变量,这似乎是您想要实现的目标:

根据MSDN

属性的访问器包含与获取(读取或计算)或设置(写入)属性相关联的可执行语句。访问器声明可以包含get访问器、set访问器或两者。声明采用以下形式:

public int EmployeeAge
{
    get;
    set;
}

看这里,它提供了关于这些用途的非常好的描述。


1
我有点晚来到这个聚会,但我想提及另一个属性和无参数“get”方法之间令人惊讶的区别。正如@MarcGravell所指出的那样,当使用属性时,延迟加载是一种常见模式,但要注意Heisenberg Watch Window陷阱!

1

属性是以简单的方式探索类内部数据元素的一种方式。我们可以使用类型安全的get和set方法实现属性。属性是通过调用约定隐式调用的。属性在编译时和运行时都起作用。

方法是包含一系列语句的代码块。方法是显式调用的。方法在运行时起作用。


0

我认为这与你所编程的文化有很大关系。在我看来,C#/.NET文化会更倾向于在这种情况下使用属性。

我的建议是:尽量与你正在使用的主要库保持一致。

但是:要注意不要过度使用属性(或者像你上面的例子中服务于同样目的的函数),因为它们通常是糟糕设计的标志。你想要“告诉”你的对象去做事情,而不是“询问”它们的信息。不要对此过于固执,只需意识到这是代码异味即可。


文化?我没有明白你的意思,因为在这两种情况下它只返回员工的年龄。 - Asim Sajjad
通过“文化”,我指的是随语言/平台提供的代码库,使用它们的开发者社区以及他们创建的库。 - Daren Thomas
我不明白你所提到的代码异味参考。如果一个复杂的对象有多个祖先,那么它可能有许多属性... - DiningPhilanderer
1
@餐厅调情者:当然可以。但是要小心这样的对象。确保你确定它需要成为什么,因为拥有许多属性可能是糟糕设计的迹象。属性往往会创建依赖关系和复杂的if/else代码。 - Daren Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接