有没有理由在接口中声明可选参数?
您可以在接口方法中声明可选参数,但不需要实现类来将参数声明为可选参数,正如Eric Lippert解释的那样 。 相反,您可以在实现类中将参数声明为可选参数,但不能在接口中声明。
那么有什么理由在接口中声明可选参数吗? 如果没有,为什么允许?
例子:
public interface IService1 { void MyMethod(string text, bool flag = false); } public class MyService1a : IService1 { public void MyMethod(string text, bool flag) {} } public class MyService1b : IService1 { public void MyMethod(string text, bool flag = true) { } } public interface IService2 { void MyMethod(string text, bool flag); } public class MyService2b : IService2 { public void MyMethod(string text, bool flag = false) { } }
例:
public interface IService1 { void MyMethod(string text, bool flag = true); } public class MyService1a : IService1 { public void MyMethod(string text, bool flag) { } }
用法:
IService1 ser = new MyService1a(); ser.MyMethod("A");
传递给MyService1a
第二个参数将为true
,作为接口中的默认参数。
这样做的原因是为了让调用者更容易使用它们的编译时类型只是接口:
public void Foo(IService1 service) { service.MyMethod("Text"); // Calls MyMethod("Text", false) }
对于调用者来说,只知道实现的接口而不是具体的类型是相当普遍的 – 所以如果你认为可选参数是一个好主意(它是有争议的),那么在接口上将它们与具体类型一样有意义。
如果一个人正在设计一个带有参数Bar
Foo
方法的接口,并且99%(但不是100%)的Foo
调用为Bar
传递零,则必须:
- 包含在接口方法中的重载包括参数`Bar`,因此要求该接口的每个实现都包含一个额外的方法,但释放调用者需要指定它。
- 只包括一个包含`Bar`的方法,为实现者节省了额外方法的成本,但需要在每个调用站点都包含一个额外的参数。
- 在接口中将参数定义为可选参数,从而使实现者和使用者更方便。
当它可行时,选项#3对我来说似乎最方便。
它非常有用,因为界面可以按照自己的方式声明它们,因此您可以在创建界面时获得所需的精确灵活性。 换句话说,派生类中的实现者可以根据需要使参数可选,可以使其成为必需等。 如果它不是可选的,派生类必须具有它。
上面的示例显示了 – 派生类的灵活性。
接口设计者对默认参数的假设可能与实现者的设计不同。
默认参数只是由编译器扩展,参数由实际默认值替换。
当您在作为接口实例的对象上调用方法时,编译器将替换接口上指定的默认值。
当您在作为类实例的对象上调用方法时,编译器将替换该类上指定的默认值。