关于c#:使用可选参数显式实现接口时发出警告

Warning From Explicitly Implementing an Interface with Optional Parameters

我在玩可选参数,看它们如何处理接口,我遇到了一个奇怪的警告。我的设置是以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
 public interface ITestInterface
 {
     void TestOptional(int a = 5, int b = 10, object c = null);
 }

 public class TestClass : ITestInterface
 {

     void ITestInterface.TestOptional(int a = 5, int b = 5, object c = null)
     {
        Console.Write("a=" + a +" b=" + b +" c=" + c);
     }
 }

编译器向我发出以下警告:

  • 为参数"a"指定的默认值无效,因为它应用于不允许可选参数的上下文中使用的成员。
  • 为参数"b"指定的默认值无效,因为它应用于不允许可选参数的上下文中使用的成员。
  • 为参数"c"指定的默认值无效,因为它应用于不允许可选参数的上下文中使用的成员。

如果我使用以下代码运行此程序:

1
2
3
4
5
6
7
8
9
class Program
{
    static void Main(string[] args)
    {
        ITestInterface test = new TestClass();
        test.TestOptional();
        Console.ReadLine();
    }
}

如我所料,我得到了"a=5 b=10 c="的输出。

我的问题是什么是警告?它指的是什么上下文?


C中可选参数的问题在于被调用方是否将对象视为TestClassITestInterface。在第一种情况下,应用类中声明的值。在第二种情况下,应用接口中声明的值。这是因为编译器使用静态可用的类型信息来构造调用。在显式接口实现的情况下,从未对方法调用"for a class",始终调用"for a interface"

10.6.1中的C语言规范规定:

If optional parameters occur in an implementing partial method declaration (§10.2.7) , an explicit interface member implementation (§13.4.1) or in a single-parameter indexer declaration (§10.9) the compiler should give a warning, since these members can never be invoked in a way that permits arguments to be omitted.


编译器告诉你

1
void ITestInterface.TestOptional(int a = 5, int b = 5, object c = null)

基本上与

1
void ITestInterface.TestOptional(int a, int b, object c)

原因是,由于您必须通过接口调用testOptional,因此接口将提供参数。在类中,没有方法没有为您提供参数值。


埃里克·利珀特的解释很清楚:为什么在接口上定义的C 4可选参数没有在实现类上强制执行?


克雷格

这些警告来自类方法实现中指定的默认值。在.NET中,参数的默认值始终由引用类型确定。当然,对于这样的显式接口实现,只能通过定义默认值的接口引用调用此方法。因此,你在课堂上所赋予的价值当然是无关紧要的,因为它永远不会被解决,你可以快乐地将其移除。IntelliSense很好,因为这里的默认值永远不会有效。

http://funcakes.posterous.com/?标记=C

http://funcakes.posterous.com/c-40-optional-parameters-default-values-and-i