2012-06-29 70 views

回答

1

擴展Check if a class is derived from a generic class,這裏是一個可能的解決方案:

 private static bool OpenGenericIsAssignableFrom1(Type openGenericType, Type typeToCheck) 
     { 
      return typeToCheck != null && typeToCheck != typeof(Object) && // Terminate recursion 
       ((typeToCheck.IsGenericType && (typeToCheck.GetGenericTypeDefinition() == openGenericType)) || // typeToCheck is as closure of openGenericType 
       OpenGenericIsAssignableFrom(openGenericType, typeToCheck.BaseType) || // typeToCheck is the subclass of a closure of openGenericType 
       typeToCheck.GetInterfaces().Any(interfaceType => OpenGenericIsAssignableFrom(openGenericType, interfaceType))); // typeToCheck inherits from an interface which is the closure of openGenericType 
     } 
+0

在這種情況下,將'c.IsAssignableFrom(一)'收益率從'c.IsAssignableFrom一個不同的結果(b)「如果a來源於b? –

+0

如果'c.IsAssignableFrom(b)'爲真,則兩者都應該返回true,如果'c.IsAssignableFrom(a)'爲假,給定爲'a:b',則兩者都爲false。但是'c.IsAssignableFrom(b)'在'c.IsAssignableFrom(a)'在它們之間時爲真,或者是'a'的接口而不是'b'時可能是錯誤的... – silasdavis

3

爲什麼不乾脆關閉打開的泛型類型,看看是否是從封閉式assingable?美中不足的是,在相同的參數關閉它可能是無效的,所以你就需要趕上

private static bool OpenGenericIsAssignableFrom(
    Type openGenericType, 
    Type typeToCheck) 
{ 
    if (!openGenericType.IsGenericType || typeToCheck == null) return false; 

    if(typeToCheck.IsGenericType) 
    { 
     var typeArgs = typeToCheck.GetGenericArguments(); 
     if (typeArgs.Length == openGenericType.GetGenericArguments().Length) 
     { 
      try 
      { 
       var closed = openGenericType.MakeGenericType(typeArgs); 
       return closed.IsAssignableFrom(typeToCheck); 
      } 
      catch 
      { 
       //violated type contraints 
       return false 
      } 
     } 
    } 
    else 
    { 
     return OpenGenericIsAssignableFrom(openGenericType, typeToCheck.BaseType) 
       || typeToCheck.GetInterfaces() 
        .Any(i=> OpenGenericIsAssignableFrom(openGenericType,i)); 
    } 
} 
+0

因爲typeToCheck的類型參數只是它的類型參數(可能不是),而不是它的超類的類型參數。例如,如果'Length:Measurement ',typeof(length).GetTypeArguments()'爲空,所以關閉'typeof(ICollection <>)'失敗。因爲'typeof(ICollection ).IsAssignableFrom(typeof(Measurement silasdavis

+0

@silasdavis足夠公平的被你的例子愚弄,只使用泛型來相信你會傳遞泛型。相應更新 –

+0

啊是的我發佈了類似的東西,但我們仍然需要爬繼承樹,請參考:IA :A 和OpenGenericIsAssignableFrom(typeof(IA <>),typeof(A )'。返回false,因爲它關閉IA '(或不能)然後停止,但'IA '可以從'A '分配'儘管它可以工作,但我認爲甚至嘗試關閉開放類型是錯誤的,除非它實際上與要檢查的類型具有相同的泛型類型,因爲這是我們真正需要的(以及接口)。 – silasdavis

相關問題