您可以在接口方法中声明可选参数,但不需要实现类将参数声明为可选,如Eric Lippert explained。相反,您可以在实现类中将参数声明为可选参数,但不能在接口中声明。
那么有什么理由在接口中声明可选参数吗?如果没有,为什么允许?
示例:
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) { }
}
答案 0 :(得分:22)
示例:
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
,作为界面中的默认参数。
答案 1 :(得分:20)
这样做的原因是为了让调用者在编译时类型只是接口时更容易使用:
public void Foo(IService1 service)
{
service.MyMethod("Text"); // Calls MyMethod("Text", false)
}
调用者通常只知道实现的接口而不是具体的类型 - 所以如果你认为可选参数是一个好主意(它是有争议的)它会产生同样的效果感觉将它们放在接口上,就像具体类型一样。
答案 2 :(得分:3)
如果设计的接口方法Foo
采用参数Bar
,则Foo
的99%(但不是100%)调用为Bar
传递零必须要么:
选项#3在我可行时似乎最方便。
答案 3 :(得分:1)
接口可以按照自己的方式声明它们,这很有用,因此您可以在创建界面时获得所需的精确灵活性。换句话说,派生类中的实现者可以根据需要使参数可选,可以使其成为必需等。如果它不是可选的,派生类必须具有它。
上面的例子表明了派生类的灵活性。
答案 4 :(得分:0)
界面设计者对默认参数的假设可能与实施者的设计不同。
默认参数只是由编译器扩展,参数由实际默认值替换。
当您在作为接口实例的对象上调用方法时,编译器将替换接口上指定的默认值。
当您在作为类实例的对象上调用方法时,编译器将替换该类上指定的默认值。