C#中的方法与属性-有啥区别[重复]

Posted

技术标签:

【中文标题】C#中的方法与属性-有啥区别[重复]【英文标题】:Method vs Property in C# - what's the difference [duplicate]C#中的方法与属性-有什么区别[重复] 【发布时间】:2010-11-20 14:49:43 【问题描述】:

可能重复:Properties vs Methods

在方法中你也可以输入一些代码和属性。例如,我有一个属性名称。当类名更改时,我想从数据库中获取一些数据并更改对象的状态。我可以添加此代码来设置我的部分属性。其他解决方案是将集合部分更改为私有并添加名为 SetName 的方法,并在此方法中添加我的代码。

那么有什么区别呢?什么时候不适合将一些代码放入 getter / setter 以及何时创建自己的方法来更改我的属性和我的类的其他部分?

【问题讨论】:

【参考方案1】:

这里有一套很好的指南,说明何时使用来自Bill Wagner 的属性和方法(固定链接)

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

对 setter 的重复调用(具有相同的值)应该与单次调用没有区别。

get 不应返回对内部数据结构的引用(参见第 23 项)。一个方法可以返回一个深拷贝,并且可以避免这个问题。

【讨论】:

+1 将其称为指南而不是规则 - 例如,延迟加载 OR 映射器通常违反了许多此指南。 当然,一切都是相对的——只有在适用时才适用。 @ChrisBallance 提供的链接返回 404。Bill Wagner 指南的有效链接是 here。无论如何都要为链接 +1,克里斯。 不允许:“设置 FirstName 属性会影响由名字 + 姓氏属性组成的只读 FullName 属性意味着这种依赖关系”哦,这对我来说是新的。我经常使用这个贴片。就像只读属性范围 = 获取 Max - Min。我认为这是一个足够快速/简单的操作,可以用作属性。所以我有点不同意这一点。 @Pedro77 我同意你的看法。我不确定这是什么原因,但我认为这不是克里斯声称的黑白答案【参考方案2】:

给定这样的属性

private string _name;
public string Name  get  return _name;  set  _name = value;  

可以写出以下两种方法:

public string get_Name()  return _name; 
public void set_Name(string value)  _name = value; 

作用相同。事实上,这正是编译器在您创建属性时为您所做的事情。

一般来说,当属性中的代码开始感觉“昂贵”时,我会避开属性,如果这有意义的话。我希望属性感觉像字段(具有在特定时间发生的受控副作用),因此它们应该是轻量级的。

【讨论】:

【参考方案3】:

属性不过是一些语法糖。 在某些情况下,最好定义一个属性而不是一个方法,因为它更清晰/更具可读性。

设计指南指出,当您要实现的功能成本很高时,应该首选方法而不是属性。

实际上,一个属性被实现为一个或两个方法;取决于您的财产是否有二传手。该属性被翻译成 get_xxx 和 set_xxx 方法。

【讨论】:

【参考方案4】:

仔细想想,属性不仅仅是语法糖。它们是您的会员数据对您会员代码的公开面孔。

因此,为您提供了一个干净的层,用于从您的代码中检索或输入成员数据的单个方面。

例如,DTO 只不过是一堆写得很好的属性,可以有效地切割数据和行为。 如果没有 DTO,您会想象将 DataGrid 或 Dropdown 紧密耦合到复杂的业务逻辑方法吗?

简单地说,方法实际上是在做这项工作......属性要么发起动作,要么获取状态。

不过,您可以在属性中使用方法代码......这不是它们的用途。甚至,如果您必须这样做,最好对属性内的另一个方法进行干净的调用,而不是实际在其中编写代码。 HTH!

【讨论】:

【参考方案5】:

每当我需要将代码放入 getter/setter 中时,我都会将代码放入私有方法中,然后从 getter/setter 中调用该方法。这样,如果我在其他地方需要,代码可以在方法调用中使用。不确定这是否是您正在寻找的答案,但这只是我使用的一种方法。

【讨论】:

完全同意。为可扩展性而设计,不是暂时的……半生不熟的黑客工作。这样做是一件简单的事情,它没有做任何事情,你正在分离事物,使它们干燥,即使你移动到一个方法的代码现在没有被重用......你永远不知道什么时候除了你自己或者当前的业务流程或需求可能需要稍后使用相同的代码。这就是质量设计。黑客是不好的。将该代码从您的属性中取出并放入一个方法中,使其更具可读性、可维护性和开放性,以便以后轻松重用...无需重构【参考方案6】:

基本上没有区别(除了setter中保留的标识符“value”)。

Getter 和 setter 在内部被翻译成标准方法,这样运行时就无法知道某个 getter 或 setter 是否与某个属性相关联。术语语法糖通常用于此类方便的构造。

但是,软件工程有一个重要的好处:如果您限制自己使用带有 get 和 set 语义的 getter 和 setter,您的代码往往更容易理解。 IE。仅执行提供相应属性所需的步骤。

做一些额外工作的常见用例是例如设置或获取不直接由成员字段支持的属性。例如,您有一个包含表示距离的值的类。您的课程可以提供两个属性:Kilometers 和 Miles 以及各自的 setter 和 getter。然后,您将在一对中进行简单的转换,并保存自己两次存储该值。

作为一般经验法则,您不应将任何代码放入具有副作用的 getter 中。此外,setter 中的代码应该具有的唯一副作用是 setter 引用的对象的状态变化。

【讨论】:

【参考方案7】:

本质上,属性是几个方法 - getProperty 和 setProperty。这只是事物的约定/简化。

假定属性 getter 没有副作用(嗯 - 它们可能具有某些副作用,例如延迟加载)。

【讨论】:

【参考方案8】:

这可能不是最重要的区别,但其中一个区别是调试器可以配置为跳过属性(假设它们的代码很简单)。

【讨论】:

以上是关于C#中的方法与属性-有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

内部设置属性有啥区别[重复]

C#中的“Main(String [] args)”和“Main(string [] args)”有啥区别[重复]

C# 中的逻辑和条件 AND、OR 有啥区别? [复制]

前后下划线的python属性有啥区别[重复]

Django rest-auth中的create和perform_create方法有啥区别[重复]

在盖茨比中,扩展组件与箭头功能有啥区别[重复]