要使用只读属性还是方法?

时间:2013-05-30 06:50:38

标签: c# .net class methods properties

我需要公开一个类实例的“ is mapped?”状态。结果由基本检查确定。 只是暴露字段的值。我不确定是否应该使用只读属性或方法。

只读属性:

public bool IsMapped
{
    get
    {
        return MappedField != null;
    }
}

方式:

public bool IsMapped()
{
    return MappedField != null;
}

我已阅读MSDN的Choosing Between Properties and Methods,但我仍然不确定。

12 个答案:

答案 0 :(得分:85)

C#标准说

  

§8.7.4

     

属性是一个成员,可以访问对象或类的特征。属性的示例包括字符串的长度,字体的大小,窗口的标题,客户的名称等。属性是字段的自然扩展。两者都是具有关联类型的命名成员,访问字段和属性的语法是相同的。但是,与字段不同,属性不表示存储位置。相反,属性具有访问器,用于指定在读取或写入值时要执行的语句。

虽然方法定义为

  

§8.7.3

     

方法是实现可由对象或类执行的计算或操作的成员。方法有一个(可能是空的)形式参数列表,一个返回值(除非方法的返回类型为void),并且是静态的或非静态的。

属性方法用于实现encapsulation。属性封装数据,方法封装逻辑。这就是为什么如果要暴露数据,您应该更喜欢只读属性。在您的情况下,没有逻辑可以修改对象的内部状态。您希望提供对对象特征的访问

对象IsMapped的实例是否是对象的特征。它包含一个检查,但这就是您拥有访问它的属性的原因。可以使用逻辑定义属性,但它们不应公开逻辑。就像第一个引用中提到的例子一样:想象一下String.Length属性。根据实现,可能是此属性循环遍历字符串并对字符进行计数。它也执行一个操作,但“从外部”它只是给出了对象的内部状态/特征的声明。

答案 1 :(得分:21)

我会使用该属性,因为没有真正的“做”(动作),没有副作用,也不是太复杂。

答案 2 :(得分:11)

我个人认为method应该做某事或执行某些操作。您未在IsMapped内执行任何操作,因此它应为property

答案 3 :(得分:7)

我要去找房产。主要是因为引用的MSDN文章的第一个句子:

  

通常,方法表示操作,属性表示数据。

答案 4 :(得分:4)

在这种情况下,我似乎很清楚它应该是一个属性。这是一个简单的检查,没有逻辑,没有副作用,没有性能影响。它没有比检查简单得多。

修改

请注意,如果 上面提到的任何一个并且你将它放入一个方法,那么该方法应该包括一个强动词,而不是像is或has这样的辅助动词。一个方法某事。你可以将它命名为VerifyMapping或DetermineMappingExistance或其他东西,只要它以动词开头即可。

答案 5 :(得分:4)

我认为您链接中的这一行是答案

  

方法表示操作,属性表示数据。

这里没有动作,只是一个数据。所以这是一个财产。

答案 6 :(得分:3)

如果您在任何时候需要添加参数以获取值,那么您需要一个方法。否则你需要一个属性

答案 7 :(得分:2)

恕我直言,第一个只读属性是正确的,因为IsMapped是你对象的一个​​属性,而你没有执行一个动作(只是一个评估),但是在一天结束时,你现有代码库的一致性可能是重要的不仅仅是语义......除非这是一个单一的任务

答案 8 :(得分:2)

我同意这里的人说,因为它正在获取数据,并且没有副作用,所以应该是属性。

为了扩展这一点,如果副作用对于“从外面看它”的人有意义,我也会接受一些副作用(但不是吸气剂)。

考虑它的一种方法是方法是动词,属性是形容词(同时,对象本身是名词,静态对象是抽象名词)。

唯一的例外动词/形容词方针是,它可以是有意义的使用方法,而不是一个属性获取时(或设置)有关的信息可能会非常昂贵:从逻辑上讲,这样的功能也许应该仍然是一个属性,但人们都习惯性的思维为低冲击性能明智的,虽然没有真正的原因应该总是这样,它可能是强调GetIsMapped()是比较重的执行明智有用如果它确实是。

在运行代码的级别上,调用属性和调用等效方法获取或设置之间绝对没有区别;这就是为编写使用它的代码的人更轻松的生活。

答案 9 :(得分:2)

在您可以访问这两种结构的情境/语言中,一般划分如下:

  • 如果请求是针对对象具有的内容,请使用属性(或字段)。
  • 如果请求是针对所做的事情的结果,请使用方法。

更具体地说,属性将用于以读取和/或写入的方式访问由于暴露属性的对象所拥有的(用于消费目的)数据成员。属性优于字段,因为数据不必一直以持久形式存在(它们允许您对计算或检索此数据值“懒惰”),并且它们比为此目的的方法更好,因为您仍然可以在代码中使用它们,就像它们是公共字段一样。

然而,属性不应导致副作用(设置变量的可能的,可理解的例外意味着保持返回的值,避免昂贵的重新计算所需的值多次);在所有其他条件相同的情况下,它们应该返回确定性结果(因此NextRandomNumber对于属性来说是一个糟糕的概念选择)并且计算不应该导致更改任何会影响其他计算的状态数据(例如,获取PropertyA和按顺序,PropertyB不应返回任何不同于获取PropertyB然后获得PropertyA的结果。

方法OTOH在概念上被理解为执行某些操作并返回结果;简而言之,它做了一些事情,可能超出计算返回值的范围。因此,当返回值的操作具有额外的副作用时,将使用这些方法。返回值可能仍然是某些计算的结果,但该方法可能已经非确定地计算(GetNextRandomNumber()),或者返回的数据是对象的唯一实例的形式,并再次调用该方法一个不同的实例,即使它可能具有相同的数据(GetCurrentStatus()),或者该方法可能会改变状态数据,使得连续两次执行完全相同的操作会产生不同的结果(EncryptDataBlock();许多加密密码以这种方式工作设计确保连续两次加密相同的数据会产生不同的密文。)

答案 10 :(得分:1)

我希望属性,因为它只返回一个字段的细节。另一方面,我希望

MappedFields[] mf;
public bool IsMapped()
{
     mf.All(x => x != null);
}

答案 11 :(得分:0)

你应该使用该属性,因为c#因此而具有属性