代码之家  ›  专栏  ›  技术社区  ›  Ben McCormack

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

  •  6
  • Ben McCormack  · 技术社区  · 16 年前

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

    实现可能如下所示:

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

    这是否可能,而不必根据提供的 propertyName ?

    3 回复  |  直到 16 年前
        1
  •  7
  •   Jon Skeet    16 年前

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

        2
  •  4
  •   Jaime    16 年前

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

    Type t = this.GetType();
    var prop = t.GetProperty(propName);
    prop.SetValue(this, value, null);
    
        3
  •  2
  •   Jordão    16 年前

    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