2010-08-09 2 views
5

Я создаю простой вспомогательный класс для хранения некоторых данных из файла, который я разбираю. Имена свойств соответствуют именам значений, которые я ожидаю найти в файле. Я хотел бы добавить метод с именем AddPropertyValue в мой класс, чтобы я мог присвоить значение свойству без явного вызова его по имени.Можно ли передать имя свойства в виде строки и присвоить ей значение?

метод будет выглядеть следующим образом:

//C# 
public void AddPropertyValue(string propertyName, string propertyValue) { 
    //code to assign the property value based on propertyName 
} 

--- 

'VB.NET' 
Public Sub AddPropertyValue(ByVal propertyName As String, _ 
          ByVal propertyValue As String) 
    'code to assign the property value based on propertyName ' 
End Sub 

Реализация может выглядеть следующим образом:

C#/VB.NET

MyHelperClass.AddPropertyValue("LocationID","5") 

Возможно ли это без того, чтобы проверить для каждого индивидуальное название собственности от поставленного propertyName?

+0

Очень похож на этот предыдущий пост: http://stackoverflow.com/questions/110562/how-to-pass-a-generic-property-as-a- параметр-to-a-function – David

ответ

7

Вы можете сделать это с отражением, позвонив по телефону Type.GetProperty, а затем PropertyInfo.SetValue. Вам нужно будет сделать соответствующую обработку ошибок, чтобы проверить, действительно ли свойство присутствует.

Вот пример:

using System; 
using System.Reflection; 

public class Test 
{ 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public void AddPropertyValue(string name, string value) 
    { 
     PropertyInfo property = typeof(Test).GetProperty(name); 
     if (property == null) 
     { 
      throw new ArgumentException("No such property!"); 
     } 
     // More error checking here, around indexer parameters, property type, 
     // whether it's read-only etc 
     property.SetValue(this, value, null); 
    } 

    static void Main() 
    { 
     Test t = new Test(); 
     t.AddPropertyValue("Foo", "hello"); 
     t.AddPropertyValue("Bar", "world"); 

     Console.WriteLine("{0} {1}", t.Foo, t.Bar); 
    } 
} 

Если вам нужно сделать, это много, это может стать довольно боль с точки зрения производительности. У делегатов есть трюки, которые могут сделать это намного быстрее, но это стоит того, чтобы заставить его работать в первую очередь.

4

С помощью отражения вы получите свойство, используя имя и установите его значение ... что-то вроде:

Type t = this.GetType(); 
var prop = t.GetProperty(propName); 
prop.SetValue(this, value, null); 
2

С точки зрения организации кода, вы могли бы сделать это в mixin-like способом (обработка помимо ошибок) :

public interface MPropertySettable { } 
public static class PropertySettable { 
    public static void SetValue<T>(this MPropertySettable self, string name, T value) { 
    self.GetType().GetProperty(name).SetValue(self, value, null); 
    } 
} 
public class Foo : MPropertySettable { 
    public string Bar { get; set; } 
    public int Baz { get; set; } 
} 

class Program { 
    static void Main() { 
    var foo = new Foo(); 
    foo.SetValue("Bar", "And the answer is"); 
    foo.SetValue("Baz", 42); 
    Console.WriteLine("{0} {1}", foo.Bar, foo.Baz); 
    } 
} 

Таким образом, вы можете использовать эту логику во многих различных классах, не жертвуя ваш драгоценный одного базовый класс с ним.

В VB.NET:

Public Interface MPropertySettable 
End Interface 
Public Module PropertySettable 
    <Extension()> _ 
    Public Sub SetValue(Of T)(ByVal self As MPropertySettable, ByVal name As String, ByVal value As T) 
    self.GetType().GetProperty(name).SetValue(self, value, Nothing) 
    End Sub 
End Module 
+1

И для get: public static string GetValue (это IPropertySettable self, имя строки) { return self.GetType(). GetProperty (name) .GetValue (self, null) .ToString() ; } –

Смежные вопросы