抽象和通用方法

Hél*_*ves 2 .net c# generics abstract-class

有这个抽象类:

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);
}
Run Code Online (Sandbox Code Playgroud)

我想制作可访问调度程序字典的特定Handler类,但每个类都会覆盖并实现自己的HandleOrder方法.

我似乎无法将该通用T应用于dictonary的代表.

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

我究竟做错了什么?

编辑

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

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

BaseOrder order = GetOrder(id);
Run Code Online (Sandbox Code Playgroud)

所以要避免这样做

if (order is OrderA) else if (order is OrderB) ...
Run Code Online (Sandbox Code Playgroud)

我创建了按类型委派的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 */ }

    ...
 }
Run Code Online (Sandbox Code Playgroud)

我像这样启动处理程序

new InsertOrderHandler().Start("123");
Run Code Online (Sandbox Code Playgroud)

Chr*_*Fin 5

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

abstract class OrderHandler<T> where T : class
Run Code Online (Sandbox Code Playgroud)


注意:
正如斯里兰姆在他的评论中已经说过的那样:一种方法不能staticabstract你一样不能 - override static方法.

所以以下方法不起作用:

public abstract static T HandleOrder<T>(OrderA order);
Run Code Online (Sandbox Code Playgroud)

你需要使用:

public abstract T HandleOrder(OrderA order); // no <T> as defined on class level
Run Code Online (Sandbox Code Playgroud)

然后你可以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)
    {
        // ...
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

var handler = new InsertOrderHandler();
handler.HandleOrder(order);
Run Code Online (Sandbox Code Playgroud)

  • 不,还有一些根本问题.`OrderDispatcher``Dictionary`是静态的,因此静态字段初始化器不能访问实例方法(实例字段初始化器也不能).我认为设计本身有问题. (4认同)
  • 同意@SriramSakthivel.似乎有5个人提​​出了一个无法解决的答案. (2认同)