是否可以将属性名称作为字符串传入并为其赋值?

我正在设置一个简单的帮助器类来保存我正在解析的文件中的一些数据。 属性的名称与我期望在文件中找到的值的名称相匹配。 我想在我的类中添加一个名为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测试每个单独的属性名称?

您可以通过调用Type.GetProperty然后调用PropertyInfo.SetValue来执行此操作。 您需要进行适当的error handling,以检查实际上不存在的属性。

这是一个示例:

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

如果你需要做很多事情,就性能而言可能会变得非常痛苦。 代表们之间的技巧可以让它快得多,但值得让它先工作。

使用reflection,您可以使用名称获取属性并设置其值…类似于:

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

在组织代码方面,您可以采用类似mixin的方式(分开error handling):

 public interface MPropertySettable { } public static class PropertySettable { public static void SetValue(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  _ 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