2013-09-21 194 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