2

哪个是更好的做法,为什么?

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

或者

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

10 回答 10

10

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

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

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

于 2009-09-07T13:15:42.867 回答
7

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

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

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

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

{
  // 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

干杯!

于 2009-09-07T13:26:22.293 回答
6

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

如果它做了很多工作,有副作用(例如,读/写它会改变你类中的其他状态),或者它可能会失败(例如抛出异常),那么最好将它写成一个 Get 方法,这样调用者可以看到它不仅仅是一个简单的值。

除此之外,它更多地取决于个人喜好(您是否认为 Properties 应该只表示具体的成员变量,或者它们是否可以用于读取“计算值”,例如您的示例中的值)。

于 2009-09-07T13:15:00.387 回答
4

一般来说:

如果您使用的语言选项#1 是合法的,那么您应该使用它。它增加了可读性,并且正是为这种工作而设计的。

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

bool getIsTodayMonday()
void setIsTodayMonday(bool timetravelingArgument)

你的例子特别

我认为您可以为两者提出论点,尽管我会选择选项#2,因为字段(在我看来)不应该进行太多计算(验证和转换除外)。

于 2009-09-07T13:11:18.440 回答
1

对我来说,我会说 IsTodayMonday 感觉更像是一种方法而不是属性,所以我会选择第二个选项 See Method vs Property in C# -一个很好的例子说明何时使用属性而不是方法有什么区别。

于 2009-09-07T13:15:34.407 回答
1

我会根据您要与用户交流的内容以及方法中发生的情况来选择。在您的示例中,我可能会选择第一个版本。如果计算更复杂,我会选择第二个版本。

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

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

于 2009-09-07T13:16:13.520 回答
1

Clock.IsTodayMonday向我建议这没有副作用或计算。

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

在您的情况下,IsTodayMonday可能是合适的,但随着它查询系统时钟,调用它可能更合适IsTodayMonday()

一个更复杂的例子可能PrimeFactors。如果您有一个名为 的整数属性PrimeFactors,它将向我表明您可以一次又一次地调用它而不会影响性能。但是,如果有一个方法被调用,PrimeFactors()那么如果我不止一次需要它,我可能会使用一个临时变量来缓存结果,尤其是在一个紧密的循环中。

于 2009-09-07T13:24:52.730 回答
0

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

于 2009-09-07T14:28:14.427 回答
0

你有没有考虑过

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

反而?这比原始方法更容易进行单元测试。

于 2009-09-07T16:47:19.317 回答
0

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

于 2009-09-17T18:29:13.490 回答