typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom
本文关键字:IsAssignableFrom GetTypeInfo lt ICollection typeof gt | 更新日期: 2023-09-27 18:32:20
我正在尝试检查以下内容
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<>) )
后者不应该肯定是真的吗?
当targetProperty.PropertyType
可以是任何类型的时,我如何获得正确的结果? 它可以是List<T>
、ObservableCollection<T>
、ReadOnlyCollection<T>
、自定义集合类型等。
您有两种开放的泛型类型。 IsAssignableFrom
将这些解释为询问是否可以从IList<T2>
分配ICollection<T1>
。一般来说,这是错误的。仅当 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.
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