多态代表

时间:2010-10-05 22:02:00

标签: c# generics interface delegates

上的C#chokes
delegate void Bar<T>(T t);

void foo(Bar bar)
{
    bar.Invoke("hello");
    bar.Invoke(42);
}

解决方法是使用界面

interface Bar
{
    void Invoke<T>(T t);
}

但是现在我需要不遗余力地定义接口的实现。我可以用代表和简单方法实现同样的目标吗?

3 个答案:

答案 0 :(得分:5)

这是不可能的,因为您无法为委托分配开放的通用方法。这是一个有趣的新功能,但目前C#不允许这样做。

可能的解决方法:

delegate void Bar(object t);

void foo(Bar bar)
{
    bar.Invoke("hello");
    bar.Invoke(42);
}

void BarMethod(object t)
{
    if (t is int)
        // ...
    else if (t is string)
        // ...
}

foo(BarMethod);

delegate void Bar<T>(T t);

void foo(Bar<string> stringBar, Bar<int> intBar)
{
    stringBar.Invoke("hello");
    intBar.Invoke(42);
}

void BarMethod<T>(T t)
{
    // ...
}

foo(BarMethod<string>, BarMethod<int>);

您已经提到的界面解决方法:

interface IBar
{
    void Invoke<T>(T t);
}

void foo(IBar bar)
{
    bar.Invoke("hello");
    bar.Invoke(42);
}

class BarType : IBar
{
    public void Invoke<T>(T t)
    {
        // ...
    }
}

foo(new BarType());

答案 1 :(得分:0)

也许你的例子并没有完全说明你的意图,但这里的仿制药有什么意义?您没有以任何有用的方式使用类型T,我会使用object而不是T

答案 2 :(得分:0)

我可以看到一些有用的东西,例如一个“SerializeSomething(T作为T)”例程,它有一个可以传递给其他泛型的类型。不幸的是,我认为这样的代表必须有一些与之相关的额外类型信息才能使这些泛型工作。例如,类型T可能不是“事物”的实际类型。如果“thing”被声明为SomeBaseType但实际上是DerivativeOfSomeBaseType,则代码SerializeSomething(thing)将调用SerializeSomething(thing)。我知道在委托机制中没有任何意义,SomeBaseType类型将被传递给委托的目标。