2011-12-13 21 views
4

我使用反射来遍历对象的属性。对于Nullable<>类型,使用PropertyType属性正在返回类型。然而,当我调用属性getter(通过PropertyType.GetGetMethod().Invoke(obj, new object[0])PropertyType.GetValue(obj, null),结果的类型是展开的原始的,未Nullable<>。对于原因的,我宁愿去成,我需要把这个结果转换成其Nullable<>类型,这将引发InvalidCastException在这种情况下:C#:动态转换基元为Nullable <>

Convert.ChangeType(property.GetValue(obj, null), property.PropertyType); 

有另一种方式,以确保该属性值的类型总是相同属性的类型

+0

“对于原因的,我宁愿不进入” - 完全取决于你,当然,但你问什么**就不能存在** - 也许你可以添加一些上下文(更改名称,如果你喜欢 - 我们不会知道或关心),我们可能会提出一个更好的选择。 –

+0

如果您确实必须知道,我将从Java到XML的XML编码器移植到C#中。我不会用另一个取代它们 - 两者都会存在并得到维护,所以我试图尽量减少它们之间的差异。我有一个'IDictionary '('IConverter'是我的),它充当属性类型的属性值转换器的注册表。由于我有这个问题,它打破了'可空'的问题。 –

+0

我使用'MakeGenericType'到所有注册的两倍的初始注册后写的代码的简要位 - 即,对于每个'type',添加相同的转换器对'typeof运算(可空<>)MakeGenericType(类型)' –

回答

5

你不能这样做,在反射的代码,因为在反射代码,你说的?约object,那里是这样的东西作为一个盒装Nullable<T> - 这是盒装基础价值,或null

如果你知道实际的类型,你可以使用构造函数来创建一个包裹价值,但它必须只能被分配到一个类型的字段/变量是Nullable<T> - 不object - 否则CLI再次解开它。

然而,对于同样的原因,你不需要它使用反射时,包裹;任何代码,如SetValue将接受object,并会做正确的事情;不管它是null还是盒装基础值,都将被正确处理。

基本上,CLI装箱和拆箱Nullable<T>,使问题void当有特殊处理。

+0

感谢你的回答。我仍然有一点需要了解C#中的拳击。由于我需要的类型是一个'IDictionary <>'键,我知道我所有的基元都被封装在'Nullable <>'中,所以我改变了一下设计来创建一个使用'(obj.GetType()。IsValueType?作为关键字的typeof(Nullable <>)。MakeGenericType(new [] {obj.GetType()}):obj.GetType())。它现在有效。 –

+1

@SteveTaylor注意* *反射级别('MakeGenericType'等)非常慢;适用于中等使用,但如果这是一个严格的循环,您*可能会*想优化一下... –

+0

感谢您的提示。 dotTrace是我的朋友。 :) –

相关问题