反射,转换列表< Int32>到IEnumerable< object> [英] Reflection, Casting List<Int32> to IEnumerable<object>
问题描述
我有一个类,需要通过对象属性进行反映,并检查值和其他内容。当我有一个列表并尝试将项目转换为IEnumerable时,一切似乎都工作异常。
if(propType.GetInterfaces ().Contains(typeof(IEnumerable)))
{
var value = prop.GetValue(source);
类型底层类型= propType.GetGenericArguments()[0];
var可枚举=值为IEnumerable< object> ;;
if(enumerable == null)
{
//问题在这里......
}
//检查list
}
propType返回为:
FullName = System.Collections.Generic.List`1 [[System.Int32,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]
底层类型返回为:
System .int32
当它是自定义类的列表时,此方法有效,当它是值类型时,它似乎正在中断。 p>
有人可以在这里帮助吗?
int
是一个值类型,在这里有所不同。根据C#规范,泛型类型之间必须进行引用或身份转换,以使类型可进行变量转换:
类型<$ c $如果
,则c> T< A1,…,An> 可方差转换为类型T< B1,…,Bn>
T
是接口或使用变量
类型参数声明的委托类型T< X1,…,Xn>
,并为每个变量类型参数Xi
保留以下条件之一:
Xi
是协变的,并且存在从Ai
到Bi
Xi
是对立的,并且是隐式引用或标识存在从Bi
到Ai
- $ b的身份转换$ b
Xi的转换
是不变的,并且存在从Ai
到Bi
IEnumerable< T>
是协变的,因此我标记的行很重要。您情况下的 Ai
是 int
,而 Bi
是 int
。从 int
到 object
没有引用转换,因为 int
不是参考类型。这两者之间也没有身份转换,因为它们不相同。
我不知道您所提问题的全部内容,但是您可以使用非通用 IEnumerable
而不是 IEnumerable< object>
。它们几乎相同。但是,您这里可能会遇到XY问题,因此在不了解您的案件的情况下很难为您提供帮助。
I have a class that i need to reflect through an object properties and check values and other things. Everything seems to be working exception when i have a list and try to convert the item to an IEnumerable.
if (propType.GetInterfaces().Contains(typeof(IEnumerable)))
{
var value = prop.GetValue(source);
Type underlyingType = propType.GetGenericArguments()[0];
var enumerable = value as IEnumerable<object>;
if(enumerable == null)
{
// problem here......
}
// Check the items in the list
}
The propType comes back as:
FullName = "System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
The underlyingType comes back as:
System.Int32
This works when it is a list of custom classes, it just seems to be breaking when it is a value type.
Can anyone help here?
The fact that int
is a value type makes the difference here. According to C# spec there must be a reference or identity conversion between generic types to make types variant-convertible:
A type
T<A1, …, An>
is variance-convertible to a typeT<B1, …, Bn>
ifT
is either an interface or a delegate type declared with the variant type parametersT<X1, …, Xn>
, and for each variant type parameterXi
one of the following holds:
Xi
is covariant and an implicit reference or identity conversion exists fromAi
toBi
Xi
is contravariant and an implicit reference or identity conversion exists fromBi
toAi
Xi
is invariant and an identity conversion exists fromAi
toBi
IEnumerable<T>
is covariant, so the line I marked is important. Ai
in your case is int
and Bi
is int
. There is no reference conversion from int
to object
, because int
is not a reference type. There is also no identity conversion between these two, because they are not the same.
I don't know the entire context of your question, but you can use non-generic IEnumerable
instead of IEnumerable<object>
. They are pretty much the same. However, you might be facing an XY problem here, so it's hard to help you without knowing more about your case.
这篇关于反射,转换列表< Int32>到IEnumerable< object>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!