2012-04-23 17 views
44

Próbuję ustawić wartość właściwości w klasie, używając ciągu znaków. Na przykład, moja klasa ma następujące właściwości:Ustawienie C#/pobieranie właściwości klasy według nazwy ciągu znaków

myClass.Name 
myClass.Address 
myClass.PhoneNumber 
myClass.FaxNumber 

Wszystkie pola są typu ciąg, więc wiem z wyprzedzeniem, że to zawsze ciąg. Teraz chcę móc ustawić właściwości za pomocą łańcucha znaków, tak jak można to zrobić z obiektem DataSet. Coś takiego:

myClass["Name"] = "John" 
myClass["Address"] = "1112 River St., Boulder, CO" 

Idealnie chcę po prostu przypisać zmienną, a następnie ustawić właściwość używając tej nazwy strun ze zmiennej

string propName = "Name" 
myClass[propName] = "John" 

czytałem o refleksji, a może to jest sposób to zrobić ale nie jestem pewien, jak to zrobić, zachowując nienaruszony dostęp do własności w klasie. Nadal chcę móc korzystać z przykładów kodu, które będą naprawdę świetne.

+0

Możliwy duplikat http://stackoverflow.com/questions/1089123/setting-a-property-by-reflection-with-a-string-value – Thomas

+0

Spójrz na to zbyt: http: // stackoverflow. com/questions/279374/how-do-i-use-net-reflection-to-search-for-property-by-name-ignoring-case – MarcinJuraszek

+0

Pamiętaj, że odbicie jest wolne. Jeśli wydajność ma znaczenie, nie jest to zalecane. –

Odpowiedz

61

Możesz dodać własność indeksatora, A pseudokod:

public class MyClass 
{ 
    public object this[string propertyName] 
    { 
     get{ 
      // probably faster without reflection: 
      // like: return Properties.Settings.Default.PropertyValues[propertyName] 
      // instead of the following 
      Type myType = typeof(MyClass);     
      PropertyInfo myPropInfo = myType.GetProperty(propertyName); 
      return myPropInfo.GetValue(this, null); 
     } 
     set{ 
      Type myType = typeof(MyClass);     
      PropertyInfo myPropInfo = myType.GetProperty(propertyName); 
      myPropInfo.SetValue(this, value, null); 

     } 

    } 
} 
+1

Myślę, że powinieneś usunąć '' 'w' GetProperty ("propertyName") 'i powinieneś użyć' SetValue' na 'zestaw' część – Marco

+0

@Marco: just done :) – Tigran

+0

Bardzo eleganckie .Dziękuję . – Patratacus

-2

Może być coś takiego?

public class PropertyExample 
{ 
    private readonly Dictionary<string, string> _properties; 

    public string FirstName 
    { 
     get { return _properties["FirstName"]; } 
     set { _properties["FirstName"] = value; } 
    } 

    public string LastName 
    { 
     get { return _properties["LastName"]; } 
     set { _properties["LastName"] = value; } 
    } 
    public string this[string propertyName] 
    { 
     get { return _properties[propertyName]; } 
     set { _properties[propertyName] = value; } 
    } 

    public PropertyExample() 
    { 
     _properties = new Dictionary<string, string>(); 
    } 
} 
+0

Należy również wypełnić słownik w konstruktorze, aby działał. –

+0

Tak, jest to tylko propozycja do dalszej implementacji. – Deitro

+0

Co wtedy, gdy rzeczywiste wartości nieruchomości są różnych typów? –

1

Możesz dodać podziałowe do swojej klasy i użyć refleksji do asów właściwości:

using System.Reflection; 

public class MyClass { 

    public object this[string name] 
    { 
     get 
     { 
      var properties = typeof(MyClass) 
        .GetProperties(BindingFlags.Public | BindingFlags.Instance); 

      foreach (var property in properties) 
      { 
       if (property.Name == name && property.CanRead) 
        return property.GetValue(this, null); 
      } 

      throw new ArgumentException("Can't find property"); 

     } 
     set { 
      return; 
     } 
    } 
} 
28

Dodaj do jakiegokolwiek Class:

public class Foo 
{ 
    public object this[string propertyName] 
    { 
     get { return this.GetType().GetProperty(propertyName).GetValue(this, null); } 
     set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); } 
    } 

    public string Bar { get; set; } 
} 

Następnie można użyć jako:

Foo f = new Foo(); 
// Set 
f["Bar"] = "asdf"; 
// Get 
string s = (string)f["Bar"]; 

Kwaśny CE: Get property value from string using reflection in C#

+0

Co z wydajnością w porównaniu do rozwiązania słownikowego? –

+0

Bardzo wolno! Ale pytanie brzmi: "Ustawienie C#/uzyskanie właściwości klasy według nazwy napisu", o "klasie", a nie o "Słowniku" –

+1

@ cristian-e, który z nich jest rozwiązaniem słownika? – dsi

Powiązane problemy