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

Jak uzyskać wartość paska, właściwość łańcucha, za pomocą odbicia? Poniższy kod wygeneruje wyjątek, jeśli typ PropertyInfo jest system.stringJak mogę uzyskać wartość właściwości ciągu za pomocą Odbicia?

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 
} 

Wydaje się, że mój problem jest to, że nieruchomość jest typem podziałowe, z System.String.

Ponadto, jak sprawdzić, czy właściwość jest indeksem?

+1

działa dobrze tutaj ... czy coś jeszcze się dzieje? – womp

+0

wygląda na to, że nie publikujesz wystarczającej ilości kodu kontekstowego? – Firoso

+0

Tak. Debugger mówi, że podstawowym typem jest ciąg, ale podejrzewam, że dzieje się coś jeszcze. – Alan

Odpowiedz

42

Można po prostu właściwość o nazwie:

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

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

sprawie wypełnienia się pytanie: podziałowe będzie zawsze nazwany Przedmiot i mają argumentów na getter. Więc

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

To jest niedokładne. Element jest domyślną nazwą dla indeksatorów, ale każdy może użyć IndererNameAttribute we właściwości indexera, aby to zmienić. Musisz wyszukać atrybut DefaultMemberAttribute na typie, aby uzyskać aktualną nazwę indeksatora. –

+1

Byłem zupełnie nieświadomy atrybutu IndexerName! Dziękuję Ci. Możesz znaleźć więcej informacji tutaj: http://bartdesmet.net/blogs/bart/archive/2006/09/09/4408.aspx Dzięki Jb Evain. – Jake

+0

Możesz w języku 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 
} 

I tu jest dla obserwacji:

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

Na podstawie innych komentarzy, będziesz musiał zmienić wartość zerową na wartość get na odpowiednią wartość indeksu. –

5

nie mogę odtworzyć problem. Czy na pewno nie próbujesz tego zrobić w przypadku niektórych obiektów z właściwościami indeksowania? W takim przypadku błąd, który napotykasz, zostanie zgłoszony podczas przetwarzania właściwości Item. Ponadto, można to zrobić:


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

Tak, to jest 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

na co właściwie polega downvote? ten kod działa zgodnie z oczekiwaniami. –

+0

Brak pomysłu. Niektóre osoby głosują tylko na głosowanie. – Alan

0

getValue z przedmiotu i wartości null pracował wielki dla mnie. Dzięki za posty.

Kontekst: Pętla przez wszystkie właściwości w modelu MVC dla nowych pracowników oraz ustalania ich formę pisał wartości:

newHire => model, z wieloma właściwościami, których pisał wartości formularza Chcę napisać indywidualnie do zestawu rekordów bazy

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

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

} 
1

Jej łatwo dostać wartość własność dowolnego obiektu metodą użycie Extension jak:

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

Użycie:

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

Dzięki Elvisowi można to zmienić na: '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

Powiązane problemy