C# 最佳实践:访问器属性还是无参数方法?

C# 最佳实践:访问器属性还是无参数方法?,c#,.net,oop,properties,accessor,C#,.net,Oop,Properties,Accessor,哪种做法更好?为什么 bool IsTodayMonday { get { return DateTime.Now.DayOfWeek == DayOfWeek.Monday; } } 或 一般情况下: 如果你使用的是选项1合法的语言,那么你应该使用它。它增加了可读性,并且正是为这种工作而设计的 如果无法使用选项#1,则应使用get/set方法;即: bool getIsTodayMonday() void setIsTodayMonday(bool timetravelingArgument

哪种做法更好?为什么

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


一般情况下:

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

如果无法使用选项#1,则应使用get/set方法;即:

bool getIsTodayMonday()
void setIsTodayMonday(bool timetravelingArgument)
你的例子特别


我认为您可以为这两种方法提供参数,尽管我会选择选项#2,因为字段(在我看来)不应该做太多的计算(除了验证和可能的转换)。

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

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


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

对于我来说,我想说IsTodayMonday更像是一种方法,而不是属性,因此我会选择第二种方法。有关何时使用属性而不是方法的示例,请参见。

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

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

在您的示例中,我将使用一个属性。

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

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


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

时钟。IsTodayMonday
对我来说,这没有副作用或计算

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

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


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

对我来说,在这种特殊情况下,这一点都不重要

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

对于.Net实现,您可能应该使用该属性。Net framework在没有使用任何参数的情况下使用IsXXX功能的属性,否则它将使用方法,除非其他一些情况表明使用方法更合适。(参见上面的文章以获取示例)

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


干杯

数据绑定在方法上不起作用,所以如果您打算将对象绑定到某个控件,请记住这一点。就个人而言,出于可读性原因,我更喜欢属性。

您考虑过吗

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

相反?这比最初的方法更容易进行单元测试。

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

困惑,你先说使用第一种方法,然后说使用第二种方法?我也对你的问题感到困惑^^^你的意思是“我通常应该使用以下哪种方法”还是“在这种情况下,我应该选择哪种方法?”。我将编辑以澄清我的意图..我想你没有抓住重点?我认为问题在于属性和方法给类用户提供了什么线索,而不是语言允许的。这就是为什么我在框架中说明了microsoft如何处理这个问题——以及“最佳实践”的好方法!当然,每一条规则都有例外。我没有资格质疑框架设计师的选择:-)我不会说
{
  // 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
public static bool IsMonday(DateTime date)
{
    return date.DayOfWeek == DayOfWeek.Monday;
}