C# 多态委托

C# 多态委托,c#,generics,interface,delegates,C#,Generics,Interface,Delegates,塞住 delegate void Bar<T>(T t); void foo(Bar bar) { bar.Invoke("hello"); bar.Invoke(42); } 代理无效条(T); 无效foo(Bar) { 调用(“你好”); 律师协会(42); } 解决方法是使用接口 interface Bar { void Invoke<T>(T t); } 接口栏 { 无效调用(T); } 但是现在我需要用自己的方式来定义接口的实现

塞住

delegate void Bar<T>(T t);

void foo(Bar bar)
{
    bar.Invoke("hello");
    bar.Invoke(42);
}
代理无效条(T);
无效foo(Bar)
{
调用(“你好”);
律师协会(42);
}
解决方法是使用接口

interface Bar
{
    void Invoke<T>(T t);
}
接口栏
{
无效调用(T);
}

但是现在我需要用自己的方式来定义接口的实现。我能用委托和简单的方法实现同样的效果吗?

也许你的例子没有完全说明你的意图,但是泛型的意义是什么?您没有以任何有用的方式使用类型T,我将使用
对象
而不是
T

这是不可能的,因为您无法将开放泛型方法分配给委托。这将是一个有趣的新特性,但目前C#不允许

可能的解决办法:

① ②
代理无效条(T);
void foo(条形stringBar、条形intBar)
{
调用stringBar.Invoke(“hello”);
intBar.Invoke(42);
}
空隙率法(T)
{
// ...
}
foo(BarMethod,BarMethod);
③ 您已经提到的界面解决方案:

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());
接口IBar
{
无效调用(T);
}
无效foo(IBar条)
{
调用(“你好”);
律师协会(42);
}
类别类型:IBar
{
公共无效调用(T)
{
// ...
}
}
foo(新的BarType());

我可以看出,拥有一个“SerializeSomething(thing as T)”例程会有一些用处,该例程的类型可以传递给其他泛型。不幸的是,我认为这样的委托必须有一些额外的类型信息与之关联,才能使这样的泛型工作。例如,类型T可能不是“事物”的实际类型。如果“thing”被声明为SomeBaseType,但实际上是一个派生的EOFSomeBaseType,那么代码SerializeSomething(thing)将调用SerializeSomething(thing)。我不知道在委托机制中,SomeBaseType将通过何种类型传递给委托的目标,这意味着什么。

您试图实现的是什么?接受
字符串的方法不能同时接受
int
。委托没有“重载”。@dtb,但委托可以接受泛型参数,并且可以推断这些类型。@Kirk-Woll:当然可以。但是,
Action
的实例仍然不能用
int
调用。并且不能有未关闭的泛型委托类型的实例。@dtb,这是真的。因此,OP的代码一开始不起作用的原因是因为参数类型
Bar
实际上并不存在——因为它代表了
Bar
中的一个离散类型。他可能打算给委托分配一个开放的泛型方法。C#目前不允许这样做。我看不出有什么好处。使用普通对象的好处是什么?静态类型。编译时类型检查。列出的解决方案很好,但问题尚未正确识别。我看不出OP的代码中有什么地方试图分配“一个开放的泛型方法给一个委托”。OP的代码无法编译,因为在没有泛型类型参数的情况下(泛型类中除外),无法声明对开放泛型委托类型实例的引用。或者可以说OP的代码中没有称为
Bar
的类型。有一种类型叫做
Bar
,但是
foo
如果不使该方法通用,就不可能接受这种类型的参数。@Ani:我想比你更进一步。想象一下,您可能有一个开放泛型委托类型的实例(不管它是被称为
Bar
还是有一些特殊语法)。你会给它分配什么?当然,这是一种开放的通用方法。
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());