2012-09-27 104 views
7

我有一種情況,我有一個類在其泛型類型參數中接受某個對象類型的實例。佈局是這樣的:在不知道類型的情況下返回泛​​型

public abstract BaseClass { ... } 
public DiamondClass : BaseClass { ... } 
public SilverClass : BaseClass { ... } 

public Handler<T> where T : BaseClass { ... } 

我想能夠創造返回的Handler<DiamondClass>Handler<BaseClass>的實例,不需要在輸入定義類型的方法。我試着沿着這些路線的東西:

public Handler<BaseClass> GetHandler(HandlerType type) 
{ 
    switch(type) 
    { 
     case HandlerType.Diamond: return new Handler<DiamondClass>(); 
     case HandlerType.Silver: return new Handler<SilverClass>(); 
     default: throw new InvalidOperationException("..."); 
    } 
} 

但是,這是行不通的,因爲很明顯Handler<DiamondClass>不會隱式轉換爲Handler<BaseClass>。我可以像這樣指定它:

public Handler<T> GetHandler<T>(HandlerType type) where T : BaseClass 
{ 
    switch(type) 
    { 
     case HandlerType.Diamond: return (Handler<T>)new Handler<DiamondClass>(); 
     case HandlerType.Silver: return (Handler<T>)new Handler<SilverClass>(); 
     default: throw new InvalidOperationException("..."); 
    } 
} 

但現在我需要調用GetHandler<DiamondClass>GetHandler<BaseClass>。而且這種方法失去了讓方法返回基於枚舉的正確處理程序的目的,而不知道類型。我希望我可以定義一個Type對象,並通過它,因爲這樣的:

Type objType = typeof(DiamondClass); 
var handler = Handler<objType>(); 

但很顯然,C#不會讓那種愚蠢的。我已經採取了幾種不同的方式,我想認爲有辦法做到這一點,但我很難過。


(我確實是通過返回dynamic對象得到這個工作,但我想避免,如果可能的話,因爲它失去了任何類型的安全性和智能感知支持。)

+0

var handler = Handler ();',我沒有看到你想要解決什麼問題。 – CaffGeek

+3

如果您必須檢查泛型方法內部的類型,我總會質疑這種方法的有用性。 –

+0

@RobA請記住,爲了解釋的緣故,我簡化了這個例子。部分問題是我希望它屬於用戶控件,並且我無法將THAT定義爲泛型,因爲它會殺死設計器。 – KChaloux

回答

9

這是其中協方差進場時,協方差和反方差僅僅只在接口和委託的工作,所以,要解決你的問題,只是定義一個新的接口IHandler共變out指定類型參數是co-variant:

public interface IHandler<out T> where T : BaseClass 
{ 
} 

具有協變型參數使它的方法比由類型參數

它將工作指定返回更多派生類型的接口。更多的信息是here

+2

+1 linkyyyy – JonH

+0

嘿,我不知道我們可以做到這一點,與類型!酷豆。我喜歡學習這些東西。編輯:剛試了一下。你是救生員。它簡化了概念的方式,而不是我認爲我必須做的事情。我很想知道爲什麼它不接受孩子作爲一種基礎。 – KChaloux

+0

@KChaloux:因爲這個東西只適用於INTERFACE和DELEGATE,如果我理解正確的話?這是什麼意思*作爲基地類型的孩子*? –

相關問題