2011-04-08 61 views
5

我有以下的一般類:如何測試兩個泛型是否具有基類 - 子類關係而不實例化它們?

class Base<T> where T : ... { ... } 
class Derived<T> : Base<T> where T : ... { ... } 
class Another<T> where T : ... { ... } 
class DerivedFromDerived<T> : Derived<T> where T : ... { ... } 

某處在我的代碼,我想從Base<T>測試是否一個給定的通用繼承,而無需創建通用的特定實例。我怎麼做?

static bool DerivedFromBase(Type type) { /* ??? */ } 

static void Main(string[] args) 
{ 
    Console.WriteLine(DerivedFromBase(typeof(Derived<>)));   // true 
    Console.WriteLine(DerivedFromBase(typeof(Another<>)));   // false 
    Console.WriteLine(DerivedFromBase(typeof(DerivedFromDerived<>))); // true 
    Console.ReadKey(true); 
} 

編輯:謝謝你馬克。現在我看到了光。我原本試過以下幾種:

typeof(Derived<>).BaseType == typeof(Base<>) 

顯然,這是正確的。 但事實並非如此。問題是Base的T是不一樣的東西Derived的T.因此,在

typeof(Base<>) 

BaseT是一個免費的類型。但是,在

typeof(Derived<>).BaseType 

BaseT勢必DerivedT,這是又一個免費類型。 (這是如此真棒我會LOVE看到System.Reflection的源代碼!)現在,

typeof(Derived<>).BaseType.GetGenericTypeDefinition() 

unbounds BaseT。結論:

typeof(Derived<>).BaseType.GetGenericTypeDefinition() == typeof(Base<>) 

現在,如果你們都對不起,我的頭就在燃燒。

+0

我感興趣的答案在這裏,因爲我覺得* *'衍生'不是Base ' – 2011-04-08 22:44:50

+0

@馬特·格里爾的'子類:的確,衍生''不'基地'的子類。 – pyon 2011-04-08 22:50:04

+0

我認爲馬克已經正確地回答了你的問題,但我認爲你可能意味着馬特上面提到的其他東西。你能澄清嗎? – briantyler 2011-04-08 22:53:51

回答

6

不知道這是你在找什麼,但我認爲「IsAssignableFrom」會做到這一點。

class Program 
{ 
    class Base<T> { } 
    class Derived<T> : Base<T> { } 
    class Another<T> { } 
    class DerivedFromDerived<T> : Derived<T> { } 

    static bool DerivedFromBase<T>(Type type) 
    { 
     return typeof(Base<T>).IsAssignableFrom(type); 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine(DerivedFromBase<int>(typeof(Derived<int>)));   // true  
     Console.WriteLine(DerivedFromBase<int>(typeof(Another<int>)));   // false  
     Console.WriteLine(DerivedFromBase<int>(typeof(DerivedFromDerived<int>))); // true 
     Console.ReadKey(true); 
    } 
} 

來處理開放式基類型:

static bool DerivedFromBase(Type type) 
    { 
     Type openBase = typeof(Base<>); 

     var baseType = type; 

     while (baseType != typeof(Object) && baseType != null) 
     { 
      if (baseType.GetGenericTypeDefinition() == openBase) return true; 

      baseType = baseType.BaseType; 
     } 
     return false; 
    } 
+0

雖然這可能不是你要找的,因爲你在原始代碼typeof(Derived <>)中處理開放泛型類型,而不是爲T提供具體類型。 – MarkPflug 2011-04-08 22:48:38

+0

我需要該函數在開放泛型上工作。否則......我將不得不重新思考(最重要的是,重做!)我的工作大約一週。 – pyon 2011-04-08 22:51:24

+0

是的,我認爲可能是這樣。增加了一個開放式測試的樣本。希望可以幫助你。 – MarkPflug 2011-04-08 22:58:53

0

我來到了這個版本,雖然它似乎有點哈克。

private static bool IsDerivedFrom(Type derivedType, Type baseType) 
{ 
    if (derivedType.BaseType == null) 
     return false; 

    if (derivedType.BaseType.GUID == baseType.GUID) 
     return true; 

    return IsDerivedFrom(derivedType.BaseType, baseType); 
} 

它依賴於具有不同的GUID所有類型的,這應該是真實的,但下週四明顯的碰撞會發生。

+0

爲什麼指導?爲什麼不直接比較? – nawfal 2013-08-28 09:52:22

相關問題