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

C# 是否可以将属性名称作为字符串传递并为其赋值?,c#,.net,vb.net,reflection,C#,.net,Vb.net,Reflection,我正在设置一个简单的助手类来保存我正在解析的文件中的一些数据。属性的名称与我希望在文件中找到的值的名称匹配。我想在我的类中添加一个名为AddPropertyValue的方法,这样我就可以为属性赋值,而无需显式地按名称调用它 方法如下所示: //C# public void AddPropertyValue(string propertyName, string propertyValue) { //code to assign the property value based on pro

我正在设置一个简单的助手类来保存我正在解析的文件中的一些数据。属性的名称与我希望在文件中找到的值的名称匹配。我想在我的类中添加一个名为
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#
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


不必根据提供的
propertyName
测试每个单独的属性名,这是可能的吗?

您可以通过调用
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);
    }
}

如果您需要经常这样做,那么在性能方面可能会非常痛苦。委托有一些技巧可以让它更快,但首先让它工作是值得的。

使用反射,您可以使用名称获取属性并设置其值。。。比如:

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

在组织代码方面,您可以采用以下方式(单独处理错误):

公共接口MPropertySettable{}
公共静态类PropertySettable{
公共静态void SetValue(此MPropertySetattable self、字符串名称、T值){
self.GetType().GetProperty(name).SetValue(self,value,null);
}
}
公共类Foo:MPropertySettable{
公共字符串条{get;set;}
公共int Baz{get;set;}
}
班级计划{
静态void Main(){
var foo=new foo();
foo.SetValue(“Bar”,“答案是”);
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
公共接口MPropertySettable
端接口
公共模块属性可附加
_
公共子集合值(T的)(ByVal self作为MPropertySettable,ByVal name作为String,ByVal值作为T)
self.GetType().GetProperty(名称).SetValue(self,value,Nothing)
端接头
端模块

与上一篇文章非常相似:对于get:public静态字符串GetValue(此IPropertySetable self,字符串名称){return self.GetType().GetProperty(name).GetValue(self,null.ToString();}
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