抽象和泛型方法

本文关键字:泛型方法 抽象 | 更新日期: 2023-09-27 18:04:21

拥有这个抽象类:

abstract class OrderHandler<T> : Handler  where T : class
{
    protected readonly Dictionary<Type, Func<BaseOrder, T>> OrderDispatcher =
         new Dictionary<Type, Func<BaseOrder, T>>
    {
        { typeof(OrderA), order => HandleOrder((OrderA) order) },
        { typeof(OrderB), order => HandleOrder((OrderB) order) },
        { typeof(OrderC), order => HandleOrder((OrderC) order) },
        { typeof(OrderD), order => HandleOrder((OrderD) order) },
    };
    public abstract T HandleOrder(OrderA order);
    public abstract T HandleOrder(OrderB order);
    public abstract T HandleOrder(OrderC order);
    public abstract T HandleOrder(OrderD order);
}
abstract class Handler
{
    public abstract Start(string orderId);
}

我想让特定的Handler类可以访问分派器字典,但每个都覆盖并实现自己的HandleOrder方法。

我似乎无法将通用的T应用于字典的委托。

类型或命名空间名称'T'无法找到(您是否缺少using指令或程序集引用?)

我做错了什么?

编辑

我想有多个类继承OrderHandler如InsertOrderHandler, DeleteOrderHandler, UpdateOrderHandler等。有许多Order对象(A, B, C,…),它们都继承了BaseOrder。

我已经有一个返回BaseOrder对象的方法,但我需要知道它是哪个子类。

BaseOrder order = GetOrder(id);

所以为了避免做

if (order is OrderA) else if (order is OrderB) ...

我创建了按类型委托的HandleOrder方法。

基本上

class InsertOrderHandler : OrderHandler<InsertOrderResult>
{
    public override Start(string orderId)
    {
        Order o = GetOrder(orderId);
        InsertOrderResult i = OrderDispatcher[o.GetType()](orderId);
    }
    public override InsertOrderResult HandleOrder(OrderA order)
    { /* do something then insert order */ }
    ...
}
class UpdateOrderHandler : OrderHandler<UpdateOrderResult>
{
    public override Start(string orderId)
    {
        Order o = GetOrder(orderId);
        UpdateOrderResult u = OrderDispatcher[o.GetType()](orderId);
    }
    public override UpdateOrderResult HandleOrder(OrderA order)
    { /* do something then update order */ }
    ...
class DeleteOrderHandler : OrderHandler<DeleteOrderResult>
{
    public override Start(string orderId)
    {
        Order o = GetOrder(orderId);
        DeleteOrderResult d = OrderDispatcher[o.GetType()](orderId);
    }
    public override DeleteOrderResult HandleOrder(OrderA order)
    { /* do something then delete order */ }
    ...
 }

我像这样启动处理程序

new InsertOrderHandler().Start("123");

抽象和泛型方法

您需要定义类的泛型约束:

abstract class OrderHandler<T> where T : class


注意:
正如Sriram在他的评论中已经说过的:一个方法不能是staticabstract,因为你不能是overridestatic -方法。

所以下面的代码不起作用:

public abstract static T HandleOrder<T>(OrderA order);

你需要使用:

public abstract T HandleOrder(OrderA order); // no <T> as defined on class level

然后您可以在自定义处理程序中override它们。当然,你需要一个对象实例来调用这些方法,OrderDispatcher也需要非static来访问实例方法。


更新问题的可能解决方案:

abstract class OrderHandler<T> where T : class
{
    protected readonly Dictionary<Type, Func<BaseOrder, T>> OrderDispatcher;
    public OrderHandler()
    {
       OrderDispatcher = new Dictionary<Type, Func<BaseOrder, T>>
       {
            { typeof(OrderA), order => HandleOrder(order as OrderA) },
            { typeof(OrderB), order => HandleOrder(order as OrderB) },
            // ...
       };
    }
    public T HandleOrder(BaseOrder order)
    {
        return OrderDispatcher[order.GetType()](order);
    }
    protected abstract T HandleOrder(OrderA order);
    // ...
}
class InsertOrderHandler : OrderHandler<InsertOrderResult>
{
    protected override InsertOrderResult HandleOrder(OrderA order)
    {
        // ...
    }
    // ...
}

然后你可以这样做:

var handler = new InsertOrderHandler();
handler.HandleOrder(order);

定义为:

abstract class OrderHandler<T>