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

Come si ottiene il valore di Bar, una proprietà stringa, tramite riflessione? Il seguente codice sarà un'eccezione se il tipo PropertyInfo è uno System.StringCome posso ottenere il valore di una proprietà stringa tramite Reflection?

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 
} 

Sembra che il mio problema è che la proprietà è un tipo di indicizzatore, con uno System.String.

Inoltre, come faccio a sapere se la proprietà è un indicizzatore?

+1

funziona bene qui ... qualcos'altro sta succedendo? – womp

+0

sembra che tu non stia pubblicando abbastanza codice contestuale? – Firoso

+0

Sì. Il debugger dice che il tipo sottostante è una stringa, ma sospetto che ci sia qualcos'altro in corso. – Alan

risposta

42

Si può solo ottenere la proprietà per nome:

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

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

Per quanto riguarda il follow-up domanda: Indicizzatori saranno sempre chiamati Voce e avere argomenti su il getter. Così

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

Non è esatto. Item è il nome predefinito per gli indicizzatori, ma chiunque può utilizzare un IndererNameAttribute sulla proprietà dell'indicizzatore per modificarlo. Devi cercare DefaultMemberAttribute sul tipo per ottenere il nome effettivo dell'indicizzatore. –

+1

Ero completamente inconsapevole dell'attributo IndexerName! Grazie. Puoi trovare maggiori informazioni qui: http://bartdesmet.net/blogs/bart/archive/2006/09/09/4408.aspx Grazie Jb Evain. – Jake

+0

È possibile 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 
} 

E qui è per il follow-up:

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

In base agli altri commenti, sarà necessario modificare il valore null per ottenere il valore corretto dei valori dell'indicizzatore. –

5

non riuscivo a riprodurre il problema. Sei sicuro di non provare a farlo su qualche oggetto con le proprietà dell'indicizzatore? In tal caso, l'errore che stai riscontrando verrebbe generato durante l'elaborazione della proprietà Item. Inoltre, si potrebbe fare questo:


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

Sì, questo è il problema. – 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

per che cosa è esattamente il downvote? questo codice funziona come previsto. –

+0

Nessuna idea. Alcune persone non votano per votare. – Alan

0

l'GetValue con oggetto e nulla ha funzionato grande per me. Grazie per i post.

Contesto: Looping attraverso tutte le strutture di un modello MVC per i nuovi assunti e determinare la loro forma ha registrato valori:

newHire => del Modello, con molte proprietà, i cui valori di forma postato voglio scrivere individualmente a un set di record del database

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

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

} 
1

sua facile valore della proprietà per ottenere di qualsiasi oggetto con il metodo di utilizzo di estensione come:

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

L'utilizzo è:

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

Grazie a Elvis questo può essere modificato in: 'return T.GetType(). GetProperty (PropName) ?. GetValue (T, null);'. https://blogs.msdn.microsoft.com/jerrynixon/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator/ – JohnLBevan