2013-10-26 43 views
0

我正在與C#泛型的煩惱:泛型在C#與「爲」和「是」有麻煩「是」檢查失敗

MappingAdapter是一種常見的抽象基類,FullMappingAdapter和LiteMappingAdapter從/繼承實行。

創建我的泛型類會議的一個實例:

session = new Session<FullMappingAdapter>(
// ... 
) 

在會議上,決定我們是什麼樣的會議:

// class declaration: 
public class Session<T> : ISession 
          where T : MappingAdapter { 
    // ... 
    // method body: 
    T t = null; 
    if (t is FullMappingAdapter) { 
     // need parameter, cannot use where T : new() above 
     t = new FullMappingAdapter(someData) as T; 
    } else if (t is LiteMappingAdapter) { 
     t = new LiteMappingAdapter(someData) as T; 
    } else { 
     throw new NotSupportedException("Unknown Adapter specified, please fix."); 
    } 

    // ... more methods here ...   

} 

我總是NotSupportedException異常拋出。另外,在調試器中查看我的堆棧時,它會在t的「類型」列中顯示「FullMappingAdapter」,這是正確的,以及我的預期。但爲什麼「is」關鍵字不能識別該類型?

我在做什麼錯?

+3

t被設置爲空,那麼'as'將如何工作? –

+0

我來自C++,僅僅因爲你將一個類的實例的指針設置爲NULL不會改變該指針的類型。它仍然是類型「指向類xyz的指針」。我假設C#也維護類型信息,即使對象引用未綁定到實際實例。認爲這是一個有效的假設,但我猜想事情在C#中的工作方式不同,感謝這些見解! – Tom

+1

C#泛型與C++模板不一樣,它在C++中的工作原理是因爲C++模板被編譯爲保護類型轉換系統的新類。在C#中,泛型類總是泛型的,類型只是另一個變量守護類型轉換,所以C#泛型在運行時會做所有事情,所以C#無法將null與任何東西進行比較。在C++中,即使某些內容爲null,編譯器也知道它的類型。 –

回答

10

null是從來沒有任何東西。

您想檢查typeof(T)是否爲精確類型(或可能爲IsAssignableFrom)。

完全匹配(不一樣is FullMappingAdapter,因爲它不包括派生類)

if(typeof(T) == typeof(FullMappingAdapter)) 

分配的 - 一樣is FullMappingAdapter

if (typeof(FullMappingAdapter).IsAssignableFrom(typeof(T)) 
+0

非常感謝你我認爲「是」仍然可以檢查一個通用參數的類型.. – Tom

+0

@Tom - 'is'可以在泛型方法中使用,只要罰款與任何地方相同的限制 - 只要值不是'你可以檢查類型是否匹配。 –

3

您應修改您的支票使用typeof

if (typeof(T) == typeof(FullMappingAdapter)) 

+0

+1:請注意,它與'FullMappingAdapter'稍有不同,因爲它不包含派生類型。 –

+0

好點,謝謝。 –

1

你必須檢查這樣

if (typeof(T) == typeof(FullMappingAdapter))