关于c#:按字符串名称设置/获取类属性

Setting/getting the class properties by string name

本问题已经有最佳答案,请猛点这里访问。

我要做的是使用字符串设置类中属性的值。例如,我的类具有以下属性:

1
2
3
4
myClass.Name
myClass.Address
myClass.PhoneNumber
myClass.FaxNumber

所有字段都是string类型,因此我提前知道它始终是字符串。现在,我希望能够像处理DataSet对象那样,使用字符串设置属性。像这样:

1
2
myClass["Name"] ="John"
myClass["Address"] ="1112 River St., Boulder, CO"

理想情况下,我只想分配一个变量,然后使用该变量中的字符串名称设置属性:

1
2
string propName ="Name"
myClass[propName] ="John"

我在读关于反射的书,也许这是做反射的方法,但我不知道如何在保持类中的属性访问完整的同时进行设置。我仍然想使用:

1
myClass.Name ="John"

任何代码示例都非常好。


可以添加索引器属性,伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyClass
{
     public object this[string propertyName]
     {
        get{
           // probably faster without reflection:
           // like:  return Properties.Settings.Default.PropertyValues[propertyName]
           // instead of the following
           Type myType = typeof(MyClass);                  
           PropertyInfo myPropInfo = myType.GetProperty(propertyName);
           return myPropInfo.GetValue(this, null);
        }
        set{
           Type myType = typeof(MyClass);                  
           PropertyInfo myPropInfo = myType.GetProperty(propertyName);
           myPropInfo.SetValue(this, value, null);

        }

     }
}

可以向类中添加索引器,并使用反射访问属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System.Reflection;

public class MyClass {

    public object this[string name]
    {
        get
        {
            var properties = typeof(MyClass)
                    .GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in properties)
            {
                if (property.Name == name && property.CanRead)
                    return property.GetValue(this, null);
            }

            throw new ArgumentException("Can't find property");

        }
        set {
            return;
        }
    }
}


可能是这样?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    public class PropertyExample
{
    private readonly Dictionary<string, string> _properties;

    public string FirstName
    {
        get { return _properties["FirstName"]; }
        set { _properties["FirstName"] = value; }
    }

    public string LastName
    {
        get { return _properties["LastName"]; }
        set { _properties["LastName"] = value; }
    }
    public string this[string propertyName]
    {
        get { return _properties[propertyName]; }
        set { _properties[propertyName] = value; }
    }

    public PropertyExample()
    {
        _properties = new Dictionary<string, string>();
    }
}