C# 显式接口实现的扩展方法绑定

C# 显式接口实现的扩展方法绑定,c#,.net,extension-methods,C#,.net,Extension Methods,为了向现有接口添加一些功能,我一直在使用扩展方法。当我隐式实现接口成员时,编译器选择接口成员实现,而不是MSDN页面中所述的扩展方法 然而,当我尝试显式实现时,似乎选择了扩展方法而不是接口的实现成员 //我的接口和此接口的扩展方法 接口文本 { 延长有效期(INTE); } 公共静态int扩展(此yapboz.IExt ext,int e) { 返回e+1; } 当我显式地实现给定的扩展方法(下面的CExt)时,它不会绑定 class-CExt:IExt { 扩展的void IExt(int

为了向现有接口添加一些功能,我一直在使用扩展方法。当我隐式实现接口成员时,编译器选择接口成员实现,而不是MSDN页面中所述的扩展方法

然而,当我尝试显式实现时,似乎选择了扩展方法而不是接口的实现成员

//我的接口和此接口的扩展方法
接口文本
{
延长有效期(INTE);
}
公共静态int扩展(此yapboz.IExt ext,int e)
{
返回e+1;
}
当我显式地实现给定的扩展方法(下面的CExt)时,它不会绑定

class-CExt:IExt
{
扩展的void IExt(int e)
{
抛出新的NotImplementedException();
}
}
在这个实现之后,它返回整数值,而不是抛出异常

然而,当我隐式地实现接口成员时(见下文),我的代码就会抛出异常

class-CExt:IExt
{
公共空间扩展(INTE)
{
抛出新的NotImplementedException();
}
}

必须通过接口调用显式实现。所以

IExt c = new CExt();
c.Extended(1);
将绑定到显式接口实现,因为变量为接口类型,但

CExt c = new CExt();
c.Extended(1);
将绑定到扩展方法,因为在
CExt
类型本身上没有公共
Extended
方法


这就是为什么它的行为如此。但是我要指出,添加与现有接口方法相同的扩展方法不是一个好主意。扩展方法用于扩展接口和类,而不是向现有接口方法添加实现。

必须通过接口调用显式实现。所以

IExt c = new CExt();
c.Extended(1);
将绑定到显式接口实现,因为变量为接口类型,但

CExt c = new CExt();
c.Extended(1);
将绑定到扩展方法,因为在
CExt
类型本身上没有公共
Extended
方法


这就是为什么它的行为如此。但是我要指出,添加与现有接口方法相同的扩展方法不是一个好主意。扩展方法用于扩展接口和类,而不是将实现添加到现有接口方法。

这是行不通的。在检查扩展方法是否存在之前,类型解析器将在接口上使用该方法。从接口中删除该方法。@MatthewWhited我想OP讨论的是创建一个
CExt
对象,并调用
Extended
,该对象将调用扩展方法,因为接口是显式实现的。@MatthewWhited我想知道隐式实现和显式实现为什么会有这样的区别?对于隐式情况,它与我预期的一样,并调用成员方法,但对于显式情况,它更喜欢扩展方法?如果接口具有与扩展方法名称相同的方法,则永远不会选择扩展方法。。。除非在静态类上显式调用它作为方法并传入实例对象。如果OP希望能够“重写”类中的方法,那么再次使用接口,但不要放置方法。如果未提供该方法,则将使用扩展方法。如果提供了本地方法,则将使用本地方法。@Deniz显式实现意味着您仅在引用具有接口类型的对象时才能看到该实现。因此,如果您执行
IExt e=new CExt();e、 扩展()
它将在
CExt
中为显式实现的方法而不是扩展方法调用实现,因为现在编译器将看到实现。这永远不会起作用。在检查扩展方法是否存在之前,类型解析器将在接口上使用该方法。从接口中删除该方法。@MatthewWhited我想OP讨论的是创建一个
CExt
对象,并调用
Extended
,该对象将调用扩展方法,因为接口是显式实现的。@MatthewWhited我想知道隐式实现和显式实现为什么会有这样的区别?对于隐式情况,它与我预期的一样,并调用成员方法,但对于显式情况,它更喜欢扩展方法?如果接口具有与扩展方法名称相同的方法,则永远不会选择扩展方法。。。除非在静态类上显式调用它作为方法并传入实例对象。如果OP希望能够“重写”类中的方法,那么再次使用接口,但不要放置方法。如果未提供该方法,则将使用扩展方法。如果提供了本地方法,则将使用本地方法。@Deniz显式实现意味着您仅在引用具有接口类型的对象时才能看到该实现。因此,如果您执行
IExt e=new CExt();e、 扩展()
它将在
CExt
中为显式实现的方法而不是扩展方法调用实现,因为现在编译器将看到实现。