2009-06-12 4 views
19
public class Foo 
{ 
    public string Bar {get; set;} 
} 

Wie bekomme ich den Wert von Bar, eine String-Eigenschaft, über Reflexion? Der folgende Code wird eine Ausnahme ausgelöst, wenn die Propertyinfo Typ ein System.String istWie kann ich den Wert einer String-Eigenschaft über Reflection erhalten?

Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

foreach(var property in f.GetType().GetProperties()) 
{ 
object o = property.GetValue(f,null); //throws exception TargetParameterCountException for String type 
} 

Es scheint, dass mein Problem ist, dass das Eigentum ist ein Indexer-Typ, mit einem System.String.

Wie kann ich feststellen, ob die Eigenschaft ein Indexer ist?

+1

funktioniert gut hier ... ist etwas anderes los? – womp

+0

scheint, als würden Sie nicht genügend Kontext-Code posten? – Firoso

+0

Ja. Der Debugger sagt, dass der zugrunde liegende Typ String ist, aber ich vermute, dass etwas anderes vor sich geht. – Alan

Antwort

42

Sie können nur die Eigenschaft von Namen erhalten:

Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

var barProperty = f.GetType().GetProperty("Bar"); 
string s = barProperty.GetValue(f,null) as string; 

In Bezug auf die Follow-up-Frage: Indexer wird immer Artikel und Argumente genannt werden auf haben der Getter. So

Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

var barProperty = f.GetType().GetProperty("Item"); 
if (barProperty.GetGetMethod().GetParameters().Length>0) 
{ 
    object value = barProperty.GetValue(f,new []{1/* indexer value(s)*/}); 
} 
+1

Das ist ungenau. Element ist der Standardname für Indexer, aber jeder kann ein IndererNameAttribute für die indexer-Eigenschaft verwenden, um dies zu ändern. Sie müssen nach dem DefaultMemberAttribute für den Typ suchen, um den tatsächlichen Indexernamen abzurufen. –

+1

Das IndexerName-Attribut war mir völlig unbekannt! Vielen Dank. Sie können weitere Informationen hier finden: http://bartdesmet.net/blogs/bart/archive/2006/09/09/4408.aspx Dank Jb Evain. – Jake

+0

Sie können in VB .. –

3
Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

foreach(var property in f.GetType().GetProperties()) 
{ 
    if(property.Name != "Bar") 
    { 
     continue; 
    } 
    object o = property.GetValue(f,null); //throws exception TargetParameterCountException for String type 
} 

Und hier ist für die Followup:

class Test 
{ 
    public class Foo 
    { 
     Dictionary<string, int> data =new Dictionary<string,int>(); 
     public int this[string index] 
     { 
      get { return data[index]; } 
      set { data[index] = value; } 
     } 

     public Foo() 
     { 
      data["a"] = 1; 
      data["b"] = 2; 
     } 
    } 

    public Test() 
    { 
     var foo = new Foo(); 
     var property = foo.GetType().GetProperty("Item"); 
     var value = (int)property.GetValue(foo, new object[] { "a" }); 
     int i = 0; 
    } 
} 
+0

Basierend auf den anderen Kommentaren müssen Sie den Nullwert bei get Wert in den richtigen Indexerwert ändern. –

5

ich das Problem nicht reproduzieren konnte. Sind Sie sicher, dass Sie dies nicht für ein Objekt mit Indexereigenschaften versuchen? In diesem Fall wird der Fehler bei der Verarbeitung der Item-Eigenschaft ausgelöst. Auch könnten Sie dies tun:


public static T GetPropertyValue<T>(object o, string propertyName) 
{ 
     return (T)o.GetType().GetProperty(propertyName).GetValue(o, null); 
} 

...somewhere else in your code... 
GetPropertyValue<string>(f, "Bar"); 
+0

Ja, das ist das Problem. – Alan

3
Foo f = new Foo(); 
f.Bar = "x"; 

string value = (string)f.GetType().GetProperty("Bar").GetValue(f, null); 
4
var val = f.GetType().GetProperty("Bar").GetValue(f, null); 
1
PropertyInfo propInfo = f.GetType().GetProperty("Bar"); 
object[] obRetVal = new Object[0]; 
string bar = propInfo.GetValue(f,obRetVal) as string; 
+0

Für was genau ist der Downvote? Dieser Code funktioniert wie erwartet. –

+0

Keine Ahnung. Manche Leute stimmen nur ab, um abzustimmen. – Alan

0

die getvalue mit dem Objekt und null für mich gearbeitet groß. Danke für die Beiträge.

Kontext: Looping durch alle Eigenschaften in einem Modell MVC für neue Mitarbeiter und die Bestimmung ihrer Form Wert geschrieben:

NewHire => das Modell, mit vielen Eigenschaften, deren geschriebene Form Werten I einzeln auf einen Satz schreiben will von Datenbankeinträgen

foreach(var propertyValue in newHire.GetProperties()) 
{ 
string propName = propertyValue.Name; 

string postedValue = newHire.GetType().GetProperty(propName).GetValue(newHire, null).ToString(); 

} 
1

Sein einfacher Eigenschaftswert von jedes Objekt durch Verwendung Erweiterung Methode, wie zu bekommen:

public static class Helper 
    { 
     public static object GetPropertyValue(this object T, string PropName) 
     { 
      return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T, null); 
     } 
    } 

Verwendung ist:

Foo f = new Foo(); 
f.Bar = "x"; 
var balbal = f.GetPropertyValue("Bar"); 
+0

Dank Elvis kann dies wie folgt geändert werden: 'return T.GetType(). GetProperty (PropName) ?. GetValue (T, null);'. https://blogs.msdn.microsoft.com/jerrynixon/2014/02/26/at-last-c-is-getting-sometimes-called-safe-navigation-operator/ – JohnLBevan

Verwandte Themen