2009-09-28 66 views
10

我嘗試動態設置Nullable <>屬性。通過反射設置屬性Nullable <>

我把我的財產例如:

PropertyInfo property = class.GetProperty("PropertyName"); // My property is Nullable<> at this time So the type could be a string or int 

我想通過反射像

property.SetValue(class,"1256",null); 

設置我的財產,我的屬性是可空<>一般它不工作。所以我試圖找到一種方法來設置我的財產。

知道我執行

Nullable.GetUnderlyingType(property.PropertyType) 

任何想法,我可空<>屬性的類型?

  • 我嘗試創建我可空<>屬性的實例與

    VAR nullVar = Activator.CreateInstance(typeof運算(可空<>)。MakeGenericType(新類型[] {Nullable.GetUnderlyingType(財產。財產種類) }));

但nullVar總是空

+0

當您設置一個整數,而不是字符串是否行得通? '「1256」是一個字符串,不是一個整數。 – 2009-09-28 18:51:13

+0

它會工作,但重點是我不知道可空屬性的類型。我可以使用Nullable.GetUnderlyingType(property.PropertyType)獲得類型 – 2009-09-28 18:57:09

+0

'Nullable <>'不能使用'string'作爲基礎類型,因爲'string'是一個引用類型。換句話說'typeof(Nullable <>)。MakeGenericType(t);'如果使用't == typeof(int)''會很好,但是會爆炸(不符合約束)'t == typeof(string) 。所以'Nullable <>'不會以任何方式作爲參考類型和可爲空值類型的一種「通用類型」。 – 2017-10-04 20:27:11

回答

13

如果你想的任意字符串轉換爲基本類型的可空的,你可以使用Convert類:

var propertyInfo = typeof(Foo).GetProperty("Bar"); 
object convertedValue = null; 
try 
{ 
    convertedValue = System.Convert.ChangeType("1256", 
     Nullable.GetUnderlyingType(propertyInfo.PropertyType)); 
} 
catch (InvalidCastException) 
{ 
    // the input string could not be converted to the target type - abort 
    return; 
} 
propertyInfo.SetValue(fooInstance, convertedValue, null); 

如果目標類型爲int,短,長的這個例子就可以了(或無符號變量,因爲輸入字符串表示非負數),double,float或decimal。警告:這不是快速的代碼。

+0

我會嘗試,在這個時候我叮叮噹噹你是我接近的答案我搜索 – 2009-09-28 19:07:51

+0

它的工作感謝 – 2009-09-28 19:11:57

+0

它的工作謝謝你 – 2013-09-23 11:46:47

9

如果它是一個可空INT,你需要使用一個int參數,而不是字符串。

property.SetValue(klass,1256,null); 

請注意對klass而不是class的更改,因爲class是保留關鍵字。如果絕對必要,你也可以使用@class(引用它)。

如果你的財產是一個通用的,那麼我認爲你可能需要使用轉換將任何你需要的東西轉換成任何東西。

var nullType = Nullable.GetUnderlyingType(property.PropertyType) 
var value = Convert.ChangeType("1256", nullType); 
property.SetValue(klass, value, null); 
+0

我知道這是一個字符串,但它是通用的,所以我不知道會是什麼類型。這只是一個例子,我的genric Nullable <>可能是一個字符串,int一般的轉換將會完成 – 2009-09-28 18:53:55

+2

由於'string'不是一個值類型,所以你不能有一個'Nullable '。 – 2009-09-28 18:55:42

2

"1256"是一個字符串,而不是一個int。

5

這裏是展示瞭如何做一個完整的例子:

using System; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Foo foo = new Foo(); 
     typeof(Foo).GetProperty("Bar") 
      .SetValue(foo, 1234, null); 
    } 
} 

class Foo 
{ 
    public Nullable<Int32> Bar { get; set; } 
} 

正如其他人所說,你需要正確的類型傳遞給SetValue功能,但你的其他反射代碼是不完全正確要麼。在查詢其成員之前,您需要獲取有關課程的類型。

編輯:如果我理解正確,你試圖設置一個字符串值通過反射的任何屬性。爲了做到這一點,你需要做一些類型檢查和類型轉換。

這裏是我的意思的例子:

using System; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Foo foo = new Foo(); 

     PropertyInfo property = typeof(Foo).GetProperty("Bar"); 
     Object value = 
      Convert.ChangeType("1234", 
       Nullable.GetUnderlyingType(property.PropertyType) 
       ?? property.PropertyType); 

     property.SetValue(foo, value, null); 
    } 
} 

class Foo 
{ 
    public Nullable<Int32> Bar { get; set; } 
} 

這種方法可以不管財產是否爲Nullable<>可以安全使用。

2

我遇到了同樣的問題,以及Convert.ChangeType不能處理Nullables上的DateTimes的問題,所以我結合了一些.NET 4動態魔術的stackoverflow解決方案來獲得我認爲是甜的東西。如果您查看代碼,我們使用動態在運行時將對象鍵入Nullable,然後運行時以不同的方式處理它,並允許將基本類型分配給可爲空的對象。

public void GenericMapField(object targetObj, string fieldName, object fieldValue) 
{ 
    PropertyInfo prop = targetObj.GetType().GetProperty(fieldName); 
    if (prop != null) 
    { 
     if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) 
     { 
      dynamic objValue = System.Activator.CreateInstance(prop.PropertyType); 
      objValue = fieldValue; 
      prop.SetValue(targetObj, (object)objValue, null); 
     } 
     else 
     { 
      prop.SetValue(targetObj, fieldValue, null); 
     } 
    } 
} 
0
public static void SetValue(object target, string propertyName, object value) 
{ 
    if (target == null) 
    return; 

    PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName); 

    object convertedValue = value; 
    if (value != null && value.GetType() != propertyInfo.PropertyType) 
    { 
    Type propertyType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; 
    convertedValue = Convert.ChangeType(value, propertyType); 
    } 

    propertyInfo.SetValue(target, convertedValue, null); 
}