【问题标题】:Why do we have to name interface method parameters?为什么我们必须命名接口方法参数?
【发布时间】:2012-01-26 16:52:16
【问题描述】:

在 C# 中,我们必须命名接口方法的参数。

我知道,即使我们不必这样做,这样做也会帮助读者理解其含义,但在某些情况下,它并不是真正需要的:

interface IRenderable
{
    void Render(GameTime);
}

我会说上面的内容和下面的内容一样具有可读性和意义:

interface IRenderable
{
    void Render(GameTime gameTime);
}

是否有一些技术原因为什么需要接口上的方法参数名称?


值得注意的是,接口方法的实现可以使用与接口方法不同的名称。

【问题讨论】:

  • 我认为这会使方法签名名称保持一致!!!
  • 我指的是方法声明在类和接口之间是一致的......

标签: c# interface parameters language-design


【解决方案1】:

我认为没有任何理由可以将此作为技术要求。但我能想到一个特别好的理由:

正如您所提到的,实现接口时不需要参数名称,并且可以轻松覆盖。
然而,当使用界面时,想象一下如果没有参数有有意义的名称会很困难!没有智能感知,没有提示,只有一种类型?呸。
这一定是始终需要名称的最大原因。

【讨论】:

  • 加上它使其与类中的方法声明保持一致。
  • "想象一下,如果没有参数有有意义的名称,会有什么困难!" - 只需在Eclipse中编写一些Java,大多数参数名称显示为“arg0”等......
  • @codesparkle 这听起来就像阅读一个缩小的 JavaScript 文件一样有趣!
  • @codesparkle:这是 Java 字节码格式的限制(参数名称不是类文件的一部分)。不过,在 Eclipse 中并不是一个真正的问题,因为它可以从 Javadoc 或源 jar 中获取它们(如果存在),然后它们不只是显示为 arg0
  • @thilo 是的,这与 Javascript 文档在 Visual Studio 中的工作方式相同。
【解决方案2】:

一个可能的原因可能是使用了可选参数。

如果我们使用接口,就不可能指定命名参数值。一个例子:

interface ITest
{
    void Output(string message, int times = 1, int lineBreaks = 1);
}

class Test : ITest
{

    public void Output(string message, int numTimes, int numLineBreaks)
    {
        for (int i = 0; i < numTimes; ++i)
        {
            Console.Write(message);
            for (int lb = 0; lb < numLineBreaks; ++lb )
                Console.WriteLine();
        }

    }
}

class Program
{
    static void Main(string[] args)
    {
        ITest testInterface = new Test();
        testInterface.Output("ABC", lineBreaks : 3);
    }
}

在这个实现中,使用接口时,timeslineBreaks上有默认参数,所以如果通过接口访问,可以使用默认值,没有命名参数我们就无法跳过times 参数并仅指定 lineBreaks 参数。

仅供参考,取决于您是通过接口还是通过类访问Output 方法来确定默认参数是否可用,以及它们的值是什么。

【讨论】:

  • 接口在可选参数和命名参数之前存在。 :)
  • @CodeCaster 好声音,很可能不是最初的原因,但现在绝对是一个原因 :) 我猜未来功能的可能性是他们命名它们的原因。
  • @Lukazoid,干得好。无论你怎么看,这都是最合乎逻辑的答案。
【解决方案3】:

好吧,这种可能性似乎太轻率了,但是——也许当你让 Visual Studio 在属性和方法中实现接口和存根时,它知道如何命名参数?

另一方面,VS 通用命名控件没有问题...

【讨论】:

    【解决方案4】:

    我想不出接口必须定义名称的任何有效技术原因。

    我可以很容易地看到名称自动实现的情况,就像今天的自动实现属性的支持成员一样。

    但是,我认为需要它们的主要原因可能有 3 个:

    1) 使用与实际方法相同的规则在编译器中实现接口验证可能要容易得多。由于直到最近才引入自动实现的属性,我怀疑这是一个重要的编译器更改。

    2) 对于那些支持在实现类中自动创建接口成员的语言(即 VB),使用预定义名称创建接口实现可能比尝试动态创建名称要容易得多。

    3) 由于接口可以在定义的应用程序之外公开,因此名称消除了与定义不明确的接口相关的歧义。

    例如,尝试实现以下接口方法:

    void Foo(string, string, int)
    

    与您的自我记录示例相比,很可能会导致更多的混乱。然而,这实际上更多是界面可用性问题而不是技术问题,尽管有人可能会争辩说,如果界面不可用,则存在潜在的技术问题。

    【讨论】:

      【解决方案5】:

      命名接口方法参数有助于自我记录:

      例如...

      interface IRenderable
      {
          void Render(TimeSpan gameTime);
      }
      

      ... 不止于此:

      interface IRenderable
      {
          void Render(TimeSpan);
      }
      

      【讨论】:

      • +1 用于自我文档,但如果您将其用于智能感知,它也有助于/// 文档。
      • 注意/// 文档,因为它可能会出错:stackoverflow.com/questions/13191542/…
      • 我同意/// 文档的好坏取决于编写它的人,并不总是必要的。但是,/// 文档有时会在您创建接口时非常有用,因为它阐明了具体类的用户和实现者之间的接口契约。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 2015-06-26
      • 2012-11-29
      相关资源
      最近更新 更多