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

Hap*_*mad 1 c# reflection portable-class-library

我想检查以下内容

typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( targetProperty.PropertyType.GetTypeInfo() )
Run Code Online (Sandbox Code Playgroud)

传入的参数IsAssignableFrom是一个IList<Something>.但它正在返回虚假.

以下内容也返回false.

typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( targetProperty.PropertyType.GetTypeInfo().GetGenericTypeDefinition() )
Run Code Online (Sandbox Code Playgroud)

即使以下情况也会返回false.

typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( typeof(IList<>) )
Run Code Online (Sandbox Code Playgroud)

难道后者肯定会回归真实吗?

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

Mik*_*ray 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.
Run Code Online (Sandbox Code Playgroud)

它似乎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.
Run Code Online (Sandbox Code Playgroud)