2014-05-21 156 views
2

有了這個抽象類:抽象和通用方法

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); 
} 

而且我要做出有機會獲得dispacher字典具體處理程序類,但每一個覆蓋並實現自己的HandleOrder方法。

我似乎無法將該通用T應用於dictonary的代表。

類型或命名空間名稱「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"); 
+1

的方法怎麼能'抽象'以及'靜態'? –

+0

到目前爲止,以下沒有答案可以幫助你。如果你可以用更多的上下文說出你想要達到的目標,這將很容易提供幫助。我希望你閱讀[我的評論在這裏](http://stackoverflow.com/questions/23783768/abstract-and-generic-methods#comment36578004_23783787) –

+0

編輯的問題...我認爲現在更清楚:) –

回答

5

您需要定義通用約束到類:

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); 
+4

否,仍然存在一些根本性問題。 'OrderDispatcher'' Dictionary'是靜態的,所以靜態字段初始值設定項不能訪問實例方法(實例字段初始值設定項都不能)。我相信設計本身有問題。 –

+2

同意@SriramSakthivel。似乎5個人已經提出了一個無法工作的答案。 –

+0

@SriramSakthivel:補充說 - 忘了這一點,謝謝。 @DanielKelley:如果'OrderDispatcher'不是'static',它也可以「工作」,但我也同意Sriram的觀點,它看起來像一般的設計問題... – ChrFin

0

把它定義爲:

abstract class OrderHandler<T>