我正在玩可选参数,看看它们如何与界面配合使用,我发现了一个奇怪的警告。我的设置是以下代码:
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);
}
}
编译器给出了以下警告:
如果我使用以下代码运行它:
class Program
{
static void Main(string[] args)
{
ITestInterface test = new TestClass();
test.TestOptional();
Console.ReadLine();
}
}
我得到了“a=5 b=10 c=
”的输出,正如我所料。
我的问题是什么警告?它指的是什么背景?
答案 0 :(得分:23)
C#中可选参数的问题是被调用者是将对象视为TestClass
还是ITestInterface
。在第一种情况下,类中声明的值适用。在第二种情况下,接口中声明的值适用。这是因为编译器使用静态可用的类型信息来构造调用。在显式接口实现的情况下,该方法永远不会被称为“类”,总是“用于接口”
10.6.1中的C#语言规范声明:
如果可选参数出现在实现部分方法声明(第10.2.7节),显式接口成员实现(第13.4.1节)或单参数索引器声明(第10.9节)中,编译器应该发出警告,因为永远不会以允许省略参数的方式调用这些成员。
答案 1 :(得分:4)
Eric Lippert在这里有一个非常明确的解释: Why are C# 4 optional parameters defined on interface not enforced on implementing class?
答案 2 :(得分:4)
编译器告诉你
void ITestInterface.TestOptional(int a = 5, int b = 5, object c = null)
与
基本相同void ITestInterface.TestOptional(int a, int b, object c)
原因是,由于您必须通过接口调用TestOptional,因此接口将提供参数。在课堂上没有办法为你提供参数值。
答案 3 :(得分:1)
克雷格,
这些警告来自类方法实现中指定的默认值。在.net中,参数的默认值始终由引用类型确定。当然,通过这样的显式接口实现,只能通过接口引用调用此方法 - 它定义了默认值。因此,它当然与你在课堂上放置的价值无关,因为它永远不会被解决,你可以愉快地删除它。鉴于此处的默认值永远不会有效,智能感知会很好。
http://funcakes.posterous.com/?tag=c
http://funcakes.posterous.com/c-40-optional-parameters-default-values-and-i