2013-09-21 169 views
0

我試圖檢查以下typeof運算(ICollection的<>).GetTypeInfo()。IsAssignableFrom(typeof運算(IList的<>))

typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(targetProperty.PropertyType.GetTypeInfo()) 

其中通入IsAssignableFrom的參數爲IList<Something>。但它正在返回假。

以下內容也會返回false。

typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(targetProperty.PropertyType.GetTypeInfo().GetGenericTypeDefinition()) 

甚至以下是返回false。

typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(typeof(IList<>)) 

不應該後者肯定會返回true?

targetProperty.PropertyType可以是任何類型時,我怎樣才能得到正確的結果?它可以是List<T>ObservableCollection<T>ReadOnlyCollection<T>,自定義收集類型等。

+0

我的第一個問題在下面得到了回答,我的第二個問題是[在此回答](http://stackoverflow.com/a/1075059/122781)。 – HappyNomad

回答

5

您有兩個開放的泛型類型。 IsAssignableFrom將這些解釋爲詢問ICollection<T1>是否可從IList<T2>轉讓。這通常是錯誤的。只有當T1 = T2時纔是如此。您需要執行一些操作來關閉具有相同類型參數的泛型類型。你可以在類型填寫爲object或者你可以得到通用的參數類型和使用:

var genericT = typeof(ICollection<>).GetGenericArguments()[0]; // a generic type parameter, T. 
bool result = typeof(ICollection<>).MakeGenericType(genericT).IsAssignableFrom(typeof(IList<>).MakeGenericType(genericT)); // willl be true. 

看來GetGenericArguments不PCL可用,並且其行爲比GenericTypeArguments性質不同。在PCL你需要使用GenericTypeParameters

var genericT = typeof(ICollection<>).GetTypeInfo().GenericTypeParameters[0]; // a generic type parameter, T. 
bool result = typeof(ICollection<>).MakeGenericType(genericT).GetTypeInfo().IsAssignableFrom(typeof(IList<>).MakeGenericType(genericT).GetTypeInfo()); // willl be true. 
+0

我在'typeof(ICollection <>).GenericTypeArguments [0]'上得到'System.IndexOutOfRangeException'。 – HappyNomad

+0

'typeof(ICollection <>).GetTypeInfo()。GenericTypeParameters'雖然。 – HappyNomad

+0

@HappyNomad GenericTypeArguments'爲泛型類型定義返回一個空數組。這就是我使用'GetGenericArguments()'的原因。 –

0

ICollection<T1>不能從IList<T2>一般分配;否則,最終可能會出現將List<char>分配給ICollection<bool>的情況。

typeof(ICollection<>).IsAssignableFrom(typeof(IList<>))   // false 
typeof(ICollection<bool>).IsAssignableFrom(typeof(List<int>)) // false 

可以,但是,從分配IList<T>ICollection<T>,前提是該類型參數T是一樣的。

typeof(ICollection<bool>).IsAssignableFrom(typeof(List<bool>)) // true 

從C#4開始,這也適用於類型的協方差:

typeof(IEnumerable<BaseClass>).IsAssignableFrom(typeof(List<DerivedClass>)));   
    // true in C# 4 
    // false in prior verions 

同樣,你可以實現他們的任何泛型類型指派非通用底座接口:

typeof(ICollection).IsAssignableFrom(typeof(List<bool>))   // true