C#扩展方法作为接口实现

51

我想知道某个类的C#扩展方法是否可以作为接口的实现?

我有:

一个接口:

public interface IEventHandler
{
    void Notify(SEvent ev, IEventEmmiter source);
}

一个实现它的类:
class Sim : IEventHandler
{

    /*public void Notify(SEvent ev, IEventEmmiter source)
    {
        Console.WriteLine("Got notified: " + ev.Name);
    }*/

}

一个包含扩展方法的类:
public static class ReflectiveEventDispatcher
{
    public static void Notify(this IEventHandler handler, SEvent ev)
    {
        if (handler.GetType().GetMethod("Handle" + ev.Name) != null)
        {
            // C# WTF?
            object[] prms = new object[0];
            prms[0] = ev;
            handler.GetType().GetMethod("Handle" + ev.Name).Invoke(handler, prms);
        }
        else
        {
            throw new System.NotImplementedException("This object doesn't have appropriate handler methods for event " + ev.Name);
        }
    }
}

现在,我希望有各种类与IEventHandler接口,并且这些接口的实现应该由扩展方法来完成。
如果不可能,那么是否可以显式定义Notify,然后只需将调用转发到扩展方法?
上面的代码基本上是多重继承的hack。是否有任何(其他)方法可以模拟此行为?
(我希望这讲得通,我习惯于Ruby,这真的让我很难受。哦,我是多么想念你,我的亲爱的mixins...)
更新
调用转发解决了它:
public void Notify(SEvent ev)
{
    ReflectiveEventDispatcher.Notify(this, ev,);
}

你甚至可以这样做:this.Notify(ev); - idanp
C# 8.0 中的默认接口方法可能有助于解决这种情况。 - DavidY
4个回答

32

不可以,扩展方法不能作为接口的实现。扩展方法只是静态方法的语法糖,其第一个参数为该类的实例,因此不属于特定类的成员,而实现接口需要满足成员函数的要求。


17

按照您描述的方式无法实现:C#方法调用解析将始终选择您方法的具体实现,而不是扩展方法。

但是,我认为如果您不在接口中定义该方法,而只是将其定义为不同命名空间中的扩展方法,则可以“有点”得到您想要的结果。当然,这是“静态”的,因为所调用的方法仍将在编译时进行选择。

实际上,您可以通过正确的“using”指令(类似于LINQ的工作方式)来选择所调用的方法。


12

这是不可能的。

接口方法必须由实现类型本身来实现。

扩展方法是纯语言级别的概念(语法糖),并不能起到帮助作用。CLR本身完全不知道扩展方法。


1
var sim = new Sim()
((IEventHandler )sim).Notify(ev)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接