Можно ли передать имя свойства в виде строки и присвоить ему значение? - PullRequest
6 голосов
/ 09 августа 2010

Я настраиваю простой вспомогательный класс для хранения некоторых данных из файла, который я анализирую.Имена свойств совпадают с именами значений, которые я ожидаю найти в файле.Я хотел бы добавить метод с именем 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?

Ответы [ 3 ]

7 голосов
/ 09 августа 2010

Вы можете сделать это с отражением, позвонив 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 голосов
/ 09 августа 2010

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

Type t = this.GetType();
var prop = t.GetProperty(propName);
prop.SetValue(this, value, null);
2 голосов
/ 10 августа 2010

С точки зрения организации кода, вы можете сделать это 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...