【问题标题】:C# Why is Delegate override not possible?C# 为什么不能进行委托覆盖?
【发布时间】:2015-08-06 01:11:29
【问题描述】:

有没有办法实现在抽象父类中使用下游委托定义?

委托和类型一样,不能被覆盖:

public abstract class ActionIssuerSimple
{
    public delegate void ActionHandler();
    ...
    public void Subscribe(ActionHandler handler) { ... }
}

public abstract class ActionIssuer<TAction> : ActionIssuerSimple
{
    public override delegate void ActionHandler(TAction parameter);
    ...
}

上面给出了错误“委托不能被覆盖”

目标是,给定SillyIssuer : ActionIssuer&lt;SillyAction&gt; 的示例,让我能够使用sillyIssuer.Subscribe((SillyAction action) =&gt; { ... });(除了将ActionIssuerSimple 用于可以运行具有签名() =&gt; { } 的处理程序的操作。因为C# 不支持在抽象类中使用下游委托定义,既不是通过abstract、泛型类型参数,也不是override,如果没有任何一个,我都找不到这样做的方法:

  1. 将所有订阅功能从 ActionIssuerSimple 复制到 ActionIssuer。这是不可取的,因为它不是 DRY。 ActionIssuerSimple 中的大部分代码都围绕着操作一系列 ActionHandler。
  2. 让所有不需要传递 Action 对象的 ActionIssuer 都传递一个,例如 int 以降低成本。这是不可取的,因为它在性能关键的应用程序的高流量核心循环中占用了不必要的内存带宽。它还在 ActionHandler 方法中给我留下了一大堆未使用的参数警告。

【问题讨论】:

  • 只能覆盖继承的虚拟成员。您的 ActionIssuer 类不继承自 ActionIssuerSimple
  • @Fabjan 即使这样做,他也无法覆盖委托。委托是一种类型,而不是成员。
  • @SriramSakthivel 我知道。我只是说要覆盖某些东西,至少应该将其标记为virtual 并首先继承它...
  • 错字,感谢收看。

标签: c# inheritance delegates


【解决方案1】:

无法覆盖委托的原因在编译的程序集中可见:

.class auto ansi sealed nested public ActionHandler
   extends [mscorlib]System.MulticastDelegate
{
} // end of class ActionHandler 

你看,ActionHandler 不是类的“真实字段”——它只是一个嵌套的密封类! :D

【讨论】:

  • 谢谢,这很有意义。那么,代表应该被视为类。似乎最好的方法,将其视为一个类,是使用类型参数和此处列出的解决方法之一stackoverflow.com/questions/191940/…
【解决方案2】:

可以使用所需的委托类型作为ActionIssuer 转换为泛型类的类型参数。

【讨论】:

  • 不幸的是,没有办法将类型参数限制为委托,因为 C# 不允许 where TActionHandler : Delegate。如果没有这样的限制,就不可能调用subscriber(action);(因为subscriber 可能是一个类实例)。
【解决方案3】:

不确定您要达到的目标。您可以覆盖属性/方法而不是类型。委托是一种类型,覆盖委托意味着什么?

我猜您需要一个通用委托,您可以将其作为ActionIssuer&lt;TAction&gt;.Subscribe 方法中的参数。

public delegate void ActionHandler<TAction>(TAction parameter);

public abstract class ActionIssuer<TAction>
{
    public void Subscribe(ActionHandler<TAction> handler) { ... }
    ...
}

那你就可以了

sillyIssuer.Subscribe((SillyAction action) => { ... });

【讨论】:

  • 这种方法有没有办法也允许无参数的ActionHandlers?这似乎是我原来帖子中不受欢迎的选项 #2。
  • @Qwertman 这将如何使用,呼叫站点是什么样的?你能举一些你想如何使用它的例子吗?
猜你喜欢
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
  • 2018-01-30
  • 1970-01-01
  • 2012-03-23
相关资源
最近更新 更多