Is it possible to pass in a property name as a string and assign a value to it?

后端 未结 3 1839
终归单人心
终归单人心 2021-01-12 18:11

I\'m setting up a simple helper class to hold some data from a file I\'m parsing. The names of the properties match the names of values that I expect to find in the file.

相关标签:
3条回答
  • 2021-01-12 18:46

    Using reflection you get the property using the name and set its value... something like:

    Type t = this.GetType();
    var prop = t.GetProperty(propName);
    prop.SetValue(this, value, null);
    
    0 讨论(0)
  • 2021-01-12 18:53

    In terms of organizing the code, you could do it in a mixin-like way (error handling apart):

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

    This way, you can reuse that logic in many different classes, without sacrificing your precious single base class with it.

    In 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
    
    0 讨论(0)
  • 2021-01-12 18:57

    You can do this with reflection, by calling Type.GetProperty and then PropertyInfo.SetValue. You'll need to do appropriate error handling to check for the property not actually being present though.

    Here's a sample:

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

    If you need to do this a lot, it can become quite a pain in terms of performance. There are tricks around delegates which can make it a lot faster, but it's worth getting it working first.

    0 讨论(0)
提交回复
热议问题