接口的可选参数

使用C#4.0 – 构build一个接口和一个实现接口的类。 我想在接口中声明一个可选参数,并将其反映在类中。 所以,我有以下几点:

public interface IFoo { void Bar(int i, int j=0); } public class Foo { void Bar(int i, int j=0) { // do stuff } } 

这编译,但它看起来不正确。 接口需要具有可选参数,否则在接口方法签名中不能正确反映。

我应该跳过可选参数,只使用可空types? 或者这样做是否会按照预期进行,没有任何副作用或后果?

你可以考虑预选参数的select:

 public interface IFoo { void Bar(int i, int j); } public static class FooOptionalExtensions { public static void Bar(this IFoo foo, int i) { foo.Bar(i, 0); } } 

如果您不喜欢新语言function的外观,则不必使用它。

真奇怪的是,在接口中为可选参数设置的值实际上是有差别的。 我想你不得不怀疑这个值是一个接口细节还是一个实现细节。 我会说后者,但事情就像前者一样。 例如下面的代码输出1 0 2 5 3 7。

 // Output: // 1 0 // 2 5 // 3 7 namespace ScrapCSConsole { using System; interface IMyTest { void MyTestMethod(int notOptional, int optional = 5); } interface IMyOtherTest { void MyTestMethod(int notOptional, int optional = 7); } class MyTest : IMyTest, IMyOtherTest { public void MyTestMethod(int notOptional, int optional = 0) { Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); } } class Program { static void Main(string[] args) { MyTest myTest1 = new MyTest(); myTest1.MyTestMethod(1); IMyTest myTest2 = myTest1; myTest2.MyTestMethod(2); IMyOtherTest myTest3 = myTest1; myTest3.MyTestMethod(3); } } } 

有趣的是,如果你的接口使得参数可选,那么实现它的类不需要做同样的事情:

 // Optput: // 2 5 namespace ScrapCSConsole { using System; interface IMyTest { void MyTestMethod(int notOptional, int optional = 5); } class MyTest : IMyTest { public void MyTestMethod(int notOptional, int optional) { Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); } } class Program { static void Main(string[] args) { MyTest myTest1 = new MyTest(); // The following line won't compile as it does not pass a required // parameter. //myTest1.MyTestMethod(1); IMyTest myTest2 = myTest1; myTest2.MyTestMethod(2); } } } 

但是,似乎有一个错误是,如果明确地实现了接口,那么在类中为可选值给出的值是毫无意义的。 在下面的例子中如何使用值9? 编译时甚至没有提示。

 // Optput: // 2 5 namespace ScrapCSConsole { using System; interface IMyTest { void MyTestMethod(int notOptional, int optional = 5); } class MyTest : IMyTest { void IMyTest.MyTestMethod(int notOptional, int optional = 9) { Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); } } class Program { static void Main(string[] args) { MyTest myTest1 = new MyTest(); // The following line won't compile as MyTest method is not available // without first casting to IMyTest //myTest1.MyTestMethod(1); IMyTest myTest2 = new MyTest(); myTest2.MyTestMethod(2); } } } 

这样的事情呢?

 public interface IFoo { void Bar(int i, int j); } public static class IFooExtensions { public static void Baz(this IFoo foo, int i, int j = 0) { foo.Bar(i, j); } } public class Foo { void Bar(int i, int j) { /* do stuff */ } } 

在实现中,您不必使参数可选。 那么你的代码会更有意义:

  public interface IFoo { void Bar(int i, int j = 0); } public class Foo { void Bar(int i, int j) { // do stuff } } 

这样,默认值是什么是明确的。 实际上,我很确定实现中的默认值不起作用,因为接口为它提供了默认值。

需要考虑的是使用Mocking框架时发生的情况,这些框架基于接口的reflection工作。 如果在接口上定义了可选参数,则将根据接口中声明的内容传递默认值。 一个问题是,没有什么能阻止你在定义上设置不同的可选值。

放在一边,这将做到你想要完成的事情。