[英]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.