typeof运算(ICollection的<>).GetTypeInfo()。IsAss

2019-10-18 16:00发布

我想检查以下

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

其中通入参数IsAssignableFromIList<Something> 。 但它返回false。

下面的方式也返回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>自定义集合类型等

Answer 1:

你有两个开放式泛型类型。 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.


Answer 2:

ICollection<T1>不能从被分配IList<T2> 一般 ; 否则,你可以用,你分配,也就是说,一个情况下最终List<char>ICollection<bool>

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

可以 ,但是,分配ICollection<T>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


文章来源: typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( typeof(IList<>) )