[英]How to get a Nullable<T> (instead of the underlying value) through FieldInfo.GetValue()?
在一个应用程序中,我有一些代码具有Nullable <int>的FieldInfo,我需要检索可以为空的值(而不是基础值),如下面的示例所示:
class Test
{
public int? value;
}
public class Program
{
static void Main(string[] args)
{
var obj = new Test { value = 10 };
var fld = typeof (Test).GetField("value");
var v = fld.GetValue(obj);
System.Diagnostics.Debug.WriteLine(v.GetType().FullName);
System.Diagnostics.Debug.WriteLine(fld.FieldType.FullName);
}
}
我的问题是,始终为v分配基础值(在此示例中为int ),而不是可为null的值(在此示例中为Nullable <int>)。
PS:真正的应用程序在编译时没有可空的类型,因此无法进行强制转换。
在此先感谢您的帮助。
在这种情况下, v
是object
类型。 如果value
为null,则v
将为null; 如果value
是某个整数,则v
将是该整数。 如果你希望v
实际上具有Nullable<int>
类型,那么你必须声明它: var v = (int?) fld.GetValue(obj);
。
如果你需要能够引用v.Value
并获得盒装值,你可能必须记录fld
为空的事实( Nullable.GetUnderlyingType(fld.FieldType) != null
)。 请注意,泛型在这里无济于事,因为您在编译时不知道T
这是你可以使用的助手:
struct NullableObject
{
public object Value { get; private set; }
public static object GetField(object Target, FieldInfo Field)
{
object value = Field.GetValue(Target);
if (Nullable.GetUnderlyingType(Field.FieldType) != null)
return new NullableObject { Value = value };
return value;
}
}
public static class NullableHelper
{
public static object GetNullableValue(this FieldInfo field, object target)
{
return NullableObject.GetField(target, field);
}
}
然后,而不是调用var v = fld.GetValue(obj);
,例如var v = fld.GetNullableValue(obj);
。 如果fld
表示Nullable类型,则将获得一个具有Value
属性的对象; 如果没有,你就会得到价值。
首先,您需要在PropertyInfo对象数组中获取“Test”类的所有属性。 形成一个循环并调用每个PropertyInfo的“PropertyType”属性的“GetGenericTypeDefinition”方法,并将其与Nullable类型进行比较。 还要检查它是否为通用类型。 如果两者都为真,则调用该PropertyInfo的“PropertyType”属性的“GetGenericArguments”方法。 这将返回“类型”对象的数组。 采取它的第一个元素。 这将是您需要的类型。
如果您有多个可空类型,那么您可以通过“PropertyInfo.Name”获取属性的名称并进行相应的比较。
以下是您可以根据需要尝试并修改的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Nullable_Demo
{
class Test
{
public int? value { get; set; }
}
class Program
{
static void Main(string[] args)
{
var obj = new Test { value = 10 };
//var fld = typeof(Test).GetField("value");
//var v = fld.GetValue(obj);
Type typeobjs = obj.GetType();
PropertyInfo[] piObjs = typeobjs.GetProperties();
foreach (PropertyInfo piObj in piObjs)
{
Type typeDefinedInNullable;
// Test for Nullable
bool isNullable = piObj.PropertyType.IsGenericType &&
piObj.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
if (isNullable)
{
// Returns the basic data type without reference to Nullable (for example, System.Int32)
typeDefinedInNullable = piObj.PropertyType.GetGenericArguments()[0];
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.