2013-09-24 18 views
1

我基本上想要做的就是有一個叫做GetHandler<T>方法返回Action<T>。 C#語法允許這個,但老實說,我不知道你應該如何實現這樣的方法。,返回相應的函數來處理參數化類型的參數泛型方法

我想基於什麼類型T是返回不同的功能,所以我現在的嘗試是這樣的:

public override Action<T> GetHandler<T>() 
    { 
     if (typeof(T) == typeof(MyType)) 
     { 
      return delegate (T t) 
      { 
       var msg = (MyType)t; 
       //do stuff 
      } 
     } 
     return null; 
    } 

這不工作,因爲它不能轉換TMyType。我也不能返回delegate (MyType msg),因爲它當然不符合簽名。

會在這種情況下的理想是什麼,如果C#允許泛型方法,您可以指定單獨的輸入,然後一個包羅萬象的覆蓋是處理一切單獨處理多個覆蓋。儘管如此,我仍然不知道如何實現這一目標。

所以,你有什麼建議我做的就是儘可能接近此功能可能嗎?我看到它的方式,我的功能幾乎可以做任何事情,因爲T不能轉換爲任何有用的東西。

下面是一個例子使用這種機制:

我們擁有一個具有實現上述行爲實例的集合類。這門課有一個方法SendMessage<T>。該方法考慮所有包含的實例並在其上調用GetHandler<T>(),檢查結果是否爲空,如果不是則向處理程序發送消息。

+0

你可以假設任何'T'?爲什麼不實現一個接口來暴露一些以通用方式導致'Func '的屬性或方法? – meilke

+0

關鍵是要有獨立的處理程序知道如何處理不同的類型。如果我開始將T約束到任何東西,我可能只需要一個'GetHandler',它總是返回剛纔處理該超類的相同函數。 –

+0

你可以舉個例子嗎?我不能完全看不出這是有用的,更多的例子可以幫助找出最好的方法 – Charleh

回答

1

你爲什麼不只是這樣做:

private void HelloMessageHandler(  HelloMessage  msg) { ... } 
private void GoodByeMessageHandler( GoodByeMessage msg) { ... } 
private void HowYaDoingMessageHandler(HowYaDoingMessage msg) { ... } 
. 
. 
. 
public Action<T> GetHandler<T>() 
{ 
    Type t = typeof(T) ; 
    Delegate handler ; 

    if  (t == typeof(HelloMessage)  ) handler = (Action<HelloMessage>)  HelloMessageHandler  ; 
    else if (t == typeof(GoodByeMessage) ) handler = (Action<GoodByeMessage>) GoodByeMessageHandler ; 
    else if (t == typeof(HowYaDoingMessage)) handler = (Action<HowYaDoingMessage>) HowYaDoingMessageHandler ; 
    else 
    { 
    string message = string.Format("Unknown Message Type specified: {0}" , t.FullName) ; 
    throw new InvalidOperationException(message); 
    } 

    Action<T> instance = (Action<T>) handler ; 
    return instance ; 
} 

看起來很簡單的給我。

+0

我不知道你可以如此寬鬆地投出代表。好的解決方案 –

1

不知道這是否會幫助,但你有沒有考慮只是約束普通?

public override Action<T> GetHandler<T>() 
    where T : SomeType // Constrain to some type/interface 
{ 
    // You can treat T like SomeType here 
} 

這樣你至少可以享受T作爲SomeType - 也許這是你所追求的?如果不是,你可以舉一個例子,以便我更好地理解你想要達到的目標嗎?

+0

我想要做的是有一個系統,每個類實現這個模式有一個'GetHandler'返回不同的功能。每個函數都需要知道如何處理特定類型的消息。然後,在處理這些類的實例時,可以執行'instance.GetHandler ()(msg)'。在我的情況下,我不能僅僅假設一個類也實現類似'HandleHello()'的東西。 –

3

不知道你需要什麼,因爲沒有給出很多方面。但你可以投出你的出路:

 return delegate (T t) 
     { 
      var msg = (MyType)(object)t; 
      //do stuff 
     } 

雙演員關閉了編譯器。這通常是要避免的。

+0

我在想我喜歡這個選項。它是如何執行的? –

+1

和以前一樣。上傳到'object'是免費的(在T是ref類型的情況下)。 – usr

+0

我對'(bool)T'沒有約束的問題。這提供了最乾淨的代碼。 – Silvermind

相關問題