2009-09-28 16 views
10

Ich versuche, eine Nullable <> Eigenschaft dynamisch festzulegen.Set-Eigenschaft Nullable <> durch Reflexion

ich meine Immobilie ab:

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

Ich mag

mein Eigentum durch Reflexion festlegen möchten
property.SetValue(class,"1256",null); 

Es funktioniert nicht, wenn mein Eigentum ein Nullable < ist> Allg. Also versuche ich einen Weg zu finden, mein Eigentum zu setzen.

die Art meiner nullable <> Immobilie erfahren i

Nullable.GetUnderlyingType(property.PropertyType) 

Jede Idee ausführen?

  • ich versuchen, eine Instanz meiner Nullable <> Immobilien mit

    var nullVar = Activator.CreateInstance (typeof (Nullable <>). Makegenerictype (neu Type [] {Nullable.GetUnderlyingType (Eigenschaft zu erstellen .Art der Immobilie) }));

Aber nullVar ist immer Null

+0

Funktioniert es, wenn Sie eine ganze Zahl anstelle einer Zeichenfolge festgelegt? '" 1256 "' ist eine Zeichenkette, keine Ganzzahl. –

+0

Es wird funktionieren, aber der Punkt ist, ich weiß nicht den Typ der Nullable-Eigenschaft. Ich könnte Nullable.GetUnderlyingType (property.PropertyType) verwenden, um den Typ –

+0

'Nullable <>' kann 'string' für den zugrunde liegenden Typ nicht verwenden, da' string' ein Referenztyp ist. Mit anderen Worten 'typeof (Nullable <>) .MakeGenericType (t);' ist in Ordnung, wenn 't == typeof (int)', aber es wird explodieren (Bedingung nicht erfüllt) mit 't == typeof (string)' . Also wird 'Nullable <> 'in keiner Weise als eine Art" gemeinsamer Typ "für Referenztypen und Nullwerttypen fungieren. –

Antwort

13

Wenn Sie eine beliebige Zeichenfolge an den zugrunde liegenden Typ des Nullable konvertieren möchten, können Sie die Convert-Klasse verwenden:

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); 

Dieses Beispiel wird funktionieren, wenn der Zieltyp int ist, kurz, lang (oder vorzeichenlose Varianten, da die Eingabezeichenfolge eine nicht negative Zahl darstellt), double, float oder decimal. Vorbehalt: Dies ist kein schneller Code.

+0

Ich werde versuchen, zu dieser Zeit, ich glaube, Sie sind die nähere Antwort ich suche –

+0

Es ist Arbeit Danke –

+0

Es funktioniert Danke –

9

Wenn es ein Nullable-int ist, müssen Sie einen int-Parameter verwenden, keinen String.

Beachten Sie die Änderung an Klasse anstelle von Klasse, da Klasse ein reserviertes Schlüsselwort ist. Sie können @class auch verwenden, wenn es absolut notwendig ist (Zitat).

Wenn Ihre Eigenschaft eine generische ist, dann denke ich, dass Sie wahrscheinlich Convert verwenden müssen, um zu konvertieren, was auch immer Sie haben, was Sie brauchen.

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

Ich weiß, dass es eine Zeichenfolge ist, aber es ist generisch, so weiß ich nicht, was der Typ sein wird. Es ist nur ein Beispiel, meine genrische Nullable <> könnte eine Zeichenkette sein, int eine generische Konvertierung wird gemacht –

+2

Sie können keine 'Nullable ' haben, da 'string' kein Werttyp ist. –

2

"1256" ist ein String, kein int.

5

Hier ist ein vollständiges Beispiel zeigt, wie es geht:

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; } 
} 

Wie andere erwähnt haben Sie die richtige Art auf die SetValue Funktion aber Ihre anderen Reflexions Code ist nicht ganz richtig entweder passieren müssen. Sie müssen den Typ der fraglichen Klasse ermitteln, bevor Sie nach seinen Mitgliedern suchen können.

Edit: Wenn ich richtig verstehe, versuchen Sie, einen String-Wert auf eine Eigenschaft über Reflexion festzulegen. Um dies zu tun, müssen Sie eine Typprüfung und Typumwandlung durchführen. Hier

ist ein Beispiel dafür, was ich meine:

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; } 
} 

Dieser Ansatz kann sicher verwendet werden, unabhängig ob die Eigenschaft ist Nullable<>.

2

Ich habe dieses Problem und auch ein Problem mit Convert.ChangeType, das DateTimes auf Nullables nicht behandelt, getroffen, also habe ich ein paar Stackoverflow-Lösungen mit etwas .NET 4 dynamischer Magie kombiniert, um etwas zu bekommen, was ich irgendwie süß finde. Wenn Sie sich den Code ansehen, verwenden wir dynamic, um das Objekt zur Laufzeit in Nullable einzufügen, dann behandelt die Laufzeit es anders und ermöglicht die Zuordnung des Basistyps zum Nullable-Objekt.

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); 
} 
Verwandte Themen