为什么Caller Information属性按照它们的方式实现?

时间:2013-07-29 21:26:59

标签: c# stack-trace callermembername

当前实施的缺点:

  • 他们违反DRY原则,因为您必须在任何需要的地方重写参数
  • 他们破坏了实现隐藏,因为你必须在接口中指定那些参数 - 即使你的接口实现中只有一个需要它们
  • 它们会污染您的界面,用户会在自动完成,文档等中看到它们。

为什么语言设计师决定反对更有用的东西,如:

public void Foo()
{
    Console.WriteLine(CallerInformation.File);
}

我猜这个实现缺少一些功能:例如如果Foo()是一个实现IFoo的类,并且IFoo在另一个程序集中,那么IFoo的任何调用者应该如何在编译时知道该信息是必需的 - 他不知道这一点。

但是!是否更好地记录这只能在一个“构建步骤”中起作用,而不是产生一些不能用作当前实现的东西?

Q1:是否有官方文档说明为什么以现在的方式实施?

Q2:有人知道其他语言有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

调用者信息属性在语义上与方法参数相关(如果没有为此字符串参数指定值,则将调用者成员名称放在其中而不是使用null作为默认值'),因此我看不出任何理由它们在语法上也不应该像目前那样相关。

  

他们违反DRY原则,因为您必须在任何需要的地方重写参数

每次想要将调用者成员名称分配给变量时,其他方法也需要做某事,例如:param = param ?? SomeExpressionToGetSomeValue

  

它们破坏了实现隐藏,因为您必须在接口中指定这些参数 - 即使您的接口实现中只有一个需要它们

关于实现隐藏:调用者有义务提供参数,所以这应该在接口中(除非运行时决定在所有调用中始终提供这样的信息,就像隐式提供参数一样 - 并提供参数在幕后隐含/神奇地对我来说似乎不是更好的方法)

关于必须指定在接口中指定那些参数 - 即使只有一个接口实现需要它们:仅指定属性和参数(如果需要)。这就是为什么Math.Abs​​被声明为公共静态int Abs(int值)而不是公共静态int Abs(int value,object ThisIsNotNeededButLetsJustHaveItHereItAnyways)

  

它们会破坏您的界面,用户会在自动完成,文档等方面看到它们。

嗯,我不明白为什么你认为这是一件坏事 - 如果来电者应该提供它的名字,它应该在文件等中。


你似乎建议你自己就像阅读堆栈框架,这将编译和运行,但可能没有你期望的那样:

private void SomeMethod()
{
    return new StackFrame(1).GetMethod().Name;
}

上面的代码将在 runtime 中获取调用者的名称,但由于内联或编译时,它可能与调用者的名称不同尾调用优化。

因此,如果该方法在编译期间(而不是运行时)需要调用者信息,则这种方法不起作用。