【问题标题】:Polymorphic delegates多态委托
【发布时间】:2010-10-05 22:01:59
【问题描述】:

C# 窒息

delegate void Bar<T>(T t);

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

解决方法是使用接口

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

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

【问题讨论】:

  • 你想要达到什么目的?采用string 的方法不能同时采用int。代表没有“重载”。
  • @dtb,但委托可以接受泛型参数,这些类型可以推断
  • @Kirk Woll:当然。但是Action&lt;string&gt; 的实例仍然不能用int 调用。而且您不能拥有未关闭的通用委托类型的实例。
  • @dtb,这是真的。因此,OP 的代码一开始就不起作用的原因是因为参数类型 Bar 实际上并不存在——因为它代表了来自 Bar&lt;T&gt; 的离散类型。

标签: c# generics interface delegates


【解决方案1】:

这是不可能的,因为您不能将开放的泛型方法分配给委托。这将是一个有趣的新功能,但目前 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());

【讨论】:

  • 列出的解决方案都很好,但没有正确识别问题。我没有看到在 OP 的代码中尝试将“一个开放的通用方法分配给一个委托”。 OP 的代码无法编译,因为无法在没有泛型类型参数的情况下声明对开放泛型委托类型实例的 reference(泛型类除外)。或者,可以说在 OP 的代码中没有名为 Bar 的类型。 一个名为Bar&lt;&gt;的类型,但是foo不可能接受这种类型的参数而不使方法通用。
  • @Ani:我想的比你更进一步。想象一下,您可以拥有一个开放的泛型委托类型的实例(不管它是称为Bar 还是有一些特殊的语法)。你会给它分配什么?当然是一个开放的泛型方法。
【解决方案2】:

也许您的示例并不能完全说明您的意图,但这里泛型的意义何在?您没有以任何有用的方式使用类型 T,我将使用 object 而不是 T

【讨论】:

  • 他可能打算为委托分配一个开放的泛型方法。 C# 目前不允许这样做。
  • 我看不到好处。使用普通对象有什么好处?
  • 静态输入。编译时类型检查。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多