0

当前实现的缺点:

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

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

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

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

但!记录这仅在一个“构建步骤”内有效而不是产生无法作为当前实现的东西不是更好吗?

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

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

4

1 回答 1

0

调用者信息属性在语义上与方法参数相关(例如“如果没有为此字符串参数指定值,则将调用者成员名称放入其中,而不是使用 null 作为默认值”),因此我认为没有理由应该这样做t 与当前的语法相关。

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

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

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

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

关于必须指定指定接口中已经存在的那些参数 - 即使只有一个接口实现需要它们:仅在需要时指定属性和参数。这就是为什么 Math.Abs​​ 被声明为 public static int Abs(int value) 而不是 public static int Abs(int value, object ThisIsNotNeededButLetsJustHaveItHereItAnyways)

它们弄脏了您的界面,用户在自动完成、文档等中看到它们。

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


您似乎建议自己类似于阅读堆栈帧,这将编译并运行,但可能不会达到您的预期:

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

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

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

于 2013-07-29T22:01:37.607 回答