2

我正在尝试检查以下内容

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

传入的参数IsAssignableFrom是一个IList<Something>. 但它返回错误。

以下也返回false。

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

甚至以下内容也返回错误。

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

后者不应该绝对返回true吗?

targetProperty.PropertyType当可以是任何类型时,我怎样才能得到正确的结果?它可以是 a List<T>、 an ObservableCollection<T>、 a ReadOnlyCollection<T>、自定义集合类型等。

4

2 回答 2

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.
于 2013-09-21T20:26:37.117 回答
1

ICollection<T1>不能从IList<T2> 一般分配;否则,您最终可能会遇到将 a 分配给 aList<char>的情况ICollection<bool>

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

但是,只要类型参数相同,您就可以分配ICollection<T>from 。IList<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
于 2013-09-21T20:26:48.170 回答