最佳实践:访问器属性或无参数方法?

时间:2009-09-07 13:06:04

标签: c# .net oop properties accessor

哪种更好的做法以及为什么?

bool IsTodayMonday { get { return DateTime.Now.DayOfWeek == DayOfWeek.Monday; } }

或者

bool IsTodayMonday()
{
    return DateTime.Now.DayOfWeek == DayOfWeek.Monday;
}

10 个答案:

答案 0 :(得分:10)

在我看来,在这些情况下使用属性,除非:

  • 电话费用昂贵,例如正在进行数据库调用
  • 致电酒店时会产生副作用,例如:其他变量也正在设置
  • 多次调用该属性会产生不同的结果
  • 您的属性仅用于设置值

在你的例子中,我会选择一个属性。

答案 1 :(得分:7)

对我来说 - 在这种特殊情况下 - 根本不重要。

如果您查看生成的IL代码,您会发现完全相同。该属性将导致创建一个生成相同IL代码的方法。

关于.Net实现,您应该使用该属性。当没有使用参数时,.Net框架使用IsXXX-Functionality的属性,否则它使用方法,除非其他一些事情表明使用方法更合适。 (有关此示例,请参见上面的帖子)

这是两个版本生成的IL-Code,如果你感兴趣的话(我使用了一个简单的控制台应用程序和静态方法/属性)

{
  // Code size       22 (0x16)
  .maxstack  2
  .locals init ([0] bool CS$1$0000,
           [1] valuetype [mscorlib]System.DateTime CS$0$0001)
  IL_0000:  nop
  IL_0001:  call       valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
  IL_0006:  stloc.1
  IL_0007:  ldloca.s   CS$0$0001
  IL_0009:  call       instance valuetype [mscorlib]System.DayOfWeek [mscorlib]System.DateTime::get_DayOfWeek()
  IL_000e:  ldc.i4.1
  IL_000f:  ceq
  IL_0011:  stloc.0
  IL_0012:  br.s       IL_0014
  IL_0014:  ldloc.0
  IL_0015:  ret
} // end of method Program::get_IsTodayProp

干杯!

答案 2 :(得分:6)

属性应该是值的一个相当简单的包装器。对于属性的用户,它应该像变量一样。

如果它有任何工作量,有副作用(例如读/写它会改变你班级中的其他状态),或者如果它可能失败(例如抛出异常),那么最好把它写成Get方法,以便调用者可以看到它不仅仅是一个简单的值。

除此之外,更多的是个人偏好(你是否认为属性应该只代表具体的成员变量,或者它们是否可以用来读取“计算值”,例如你的例子中的那个)。

答案 3 :(得分:4)

<强>一般

如果您使用的是选项#1合法的语言,那么您应该使用它。它提高了可读性,而且它完全适用于这种工作。

如果你不能使用选项#1,你应该使用get / set方法;即:

bool getIsTodayMonday()
void setIsTodayMonday(bool timetravelingArgument)

您的示例

我认为你可以为两者提出论据,虽然我选择#2作为字段(在我看来)不应该做太多的计算(除了验证和转换)。

答案 4 :(得分:1)

对我来说,我会说IsTodayMonday更像是一种方法而不是一种属性,所以我会选择第二个选项参见Method vs Property in C# - what's the difference,以获得何时使用属性而非方法的一个很好的例子。

答案 5 :(得分:1)

我会根据您想要与用户沟通的内容以及该方法中发生的情况进行选择。在你的例子中,我可能会选择第一个版本。如果计算更复杂,我会选择第二个版本。

或者从用户的角度来看:我不介意多次访问obj.IsTodayMonday,因为我认为它不需要繁重的计算。在obj.IsTodayMonday()的情况下,我会考虑缓存并重用结果。

但这当然是我编写代码的方式。这取决于您的政策。

答案 6 :(得分:1)

Clock.IsTodayMonday告诉我,这没有任何副作用或计算。

Clock.IsTodayMonday()表示可能存在副作用或计算。

在您的情况下,IsTodayMonday可能是合适的,但在查询系统时钟时,可能更适合将其称为IsTodayMonday()

更复杂的例子可能是PrimeFactors。如果你有一个名为PrimeFactors的整数属性,它会告诉我你可以一次又一次地调用它而不会有任何性能损失。但是,如果有一个名为PrimeFactors()的方法,那么我可能会使用临时变量来缓存结果,如果我不止一次需要它,特别是在紧密循环中。

答案 7 :(得分:0)

DataBinding不适用于方法,因此如果您打算将对象绑定到某个控件,请记住这一点。出于可读性原因,我个人更喜欢属性。

答案 8 :(得分:0)

您是否考虑过

public static bool IsMonday(DateTime date)
{
    return date.DayOfWeek == DayOfWeek.Monday;
}

代替?这比单独的方法更容易进行单元测试。

答案 9 :(得分:0)

我在设计软件方面拥有二十年左右的经验,担任过许多不同公司的顾问,并且一直在OEM公司工作。 对我来说,这个问题更像是公司政策(编码指南)问题,如果有任何公司想要选择有助于产生易于理解和易于调试和阅读的方法,那么他们应该选择使用Get / Set over属性。 这是因为,例如,当调试使用来自其他类的属性的调用类时,它似乎就像一个可能没有很好处理的公共变量访问(BAD并且看起来很危险)。另一方面,如果您在那里看到Getter / Setter方法调用,那么您将立即知道它不是公共变量访问,并且有一个处理该调用的函数,它甚至可以返回错误代码或异常如果这样选择的话。 任何编码指南或实践选择应该基于这样的事实,即选择更好地指导编码人员编写快速可理解,可信(安全),便携,简单和对称的代码,这些代码是调试友好的。还有其他原因吗?