2012-03-02 20 views
2

不知道我是否可以做到這一點,但我試圖查看一個類型是否繼承了具有通用約束的另一個類型。IsAssignableFrom GenericType

這裏是我想要找的類:

public class WorkoutCommentStreamMap : ClassMapping<WorkoutCommentStream>... 

這裏是測試

var inheritableType = typeof(NHibernate.Mapping.ByCode.Conformist.ClassMapping<>); 
var isMappedObject = inheritableType.IsAssignableFrom(typeof(WorkoutCommentStreamMap)); 

如果我改變第一線以下,它的工作原理。但是這打破了我的例子的目的。我的回退工作是在所有想找到的對象上使用相同的調用,並將自定義非通用接口。

var inheritableType = typeof(NHibernate.Mapping.ByCode.Conformist.ClassMapping<WorkoutCommentStream>); 

回答

7

沒有泛型類型定義和封閉泛型類型之間的繼承關係。因此,IsAssignableFrom將無法​​正常工作。

但是,我用這個小擴展方法來實現你以後有什麼:

public static bool IsGenericTypeOf(this Type t, Type genericDefinition) 
{ 
    Type[] parameters = null; 
    return IsGenericTypeOf(t, genericDefinition, out parameters); 
} 

public static bool IsGenericTypeOf(this Type t, Type genericDefinition, out Type[] genericParameters) 
{ 
    genericParameters = new Type[] { }; 
    if (!genericDefinition.IsGenericType) 
    { 
     return false; 
    } 

    var isMatch = t.IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition(); 
    if (!isMatch && t.BaseType != null) 
    { 
     isMatch = IsGenericTypeOf(t.BaseType, genericDefinition, out genericParameters); 
    } 
    if (!isMatch && genericDefinition.IsInterface && t.GetInterfaces().Any()) 
    { 
     foreach (var i in t.GetInterfaces()) 
     { 
      if (i.IsGenericTypeOf(genericDefinition, out genericParameters)) 
      { 
       isMatch = true; 
       break; 
      } 
     } 
    } 

    if (isMatch && !genericParameters.Any()) 
    { 
     genericParameters = t.GetGenericArguments(); 
    } 
    return isMatch; 
} 

隨着樣品用量:

Nullable<int> value = 9; 
Assert.IsTrue(value.GetType().IsGenericTypeOf(typeof(Nullable<>))); 
+0

神奇奇幻 – Trent 2012-03-02 20:14:31

1

從未有MyType<>MyType<T>MyType<ConcreteType>之間的繼承關係!因此,他們永遠不會分配兼容。

一個例外是接口類型具有通用參數inout關鍵字。

3

你想要做什麼都不行,和它在MSDN documentation明確提出了原因:

泛型類型定義從一個封閉構造 類型是不可轉讓。也就是說,你不能在封閉構造類型 MyGenericList<int>賦給類型MyGenericList<T>

IsAssignableFrom似乎有點小題大做這裏的變量;你可以使用BaseType來檢查匹配類型嗎?

+0

DOH!就在我看到的頁面上。謝謝。 – Trent 2012-03-02 20:11:29

+0

@Trent:請注意,如果您希望包含「WorkoutCommentStreamMap」的子類,則需要上級。 – 2012-03-02 20:35:32

+0

@Reddog有最佳答案。我可以滾動到我的linq查詢中,而且它仍然很漂亮。 – Trent 2012-03-02 21:00:02

4

您可以使用BaseTypeIsGenericTypeGetGenericTypeDefinition遞歸了層次結構,並設法找到它:

public bool IsClassMapping(Type t) 
{ 
    while (t != null) 
    { 
     if (t.IsGenericType && 
      t.GetGenericTypeDefinition() == typeof(ClassMapping<>)) 
     { 
      return true; 
     } 
     t = t.BaseType; 
    } 
    return false; 
} 
0

或許這將幫助?

public static bool IsConcreteGenericOf(this Type type, Type openGeneric) 
    { 
     if (!type.IsGenericType) 
      return false; 
     if (!openGeneric.IsGenericType) 
      return false; 
     if (!openGeneric.IsGenericTypeDefinition) 
      return false; 

     return type.GetGenericTypeDefinition() == openGeneric; 
    } 

Sorta simlar對喬恩Skeet的答案,他擊敗了我。

+1

隨着400k +我認爲Skeet擊敗了很多人 – Trent 2012-03-02 20:25:37

+0

大聲笑,這是真的。 – Ani 2012-03-02 20:50:42

相關問題