在c#中是否有一种方法,我可以使用反射来设置对象属性?

Ex:

MyObject obj = new MyObject();
obj.Name = "Value";

我要设置obj。带有反射的名称。喜欢的东西:

Reflection.SetProperty(obj, "Name") = "Value";

有什么办法可以做到吗?


当前回答

是的,你可以使用type . invokember ():

using System.Reflection;
MyObject obj = new MyObject();
obj.GetType().InvokeMember("Name",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
    Type.DefaultBinder, obj, "Value");

如果obj没有名为Name的属性,或者它无法设置,这将抛出异常。

另一种方法是获取属性的元数据,然后对其进行设置。这将允许你检查属性是否存在,并验证它是否可以被设置:

using System.Reflection;
MyObject obj = new MyObject();
PropertyInfo prop = obj.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
if(null != prop && prop.CanWrite)
{
    prop.SetValue(obj, "Value", null);
}

其他回答

你还可以:

Type type = target.GetType();

PropertyInfo prop = type.GetProperty("propertyName");

prop.SetValue (target, propertyValue, null);

其中target是将设置其属性的对象。

是的,使用系统。反射:

using System.Reflection;

...

    string prop = "name";
    PropertyInfo pi = myObject.GetType().GetProperty(prop);
    pi.SetValue(myObject, "Bob", null);

或者你可以在你自己的扩展类中包装Marc的一行代码:

public static class PropertyExtension{       

   public static void SetPropertyValue(this object obj, string propName, object value)
    {
        obj.GetType().GetProperty(propName).SetValue(obj, value, null);
    }
}

像这样叫它:

myObject.SetPropertyValue("myProperty", "myValue");

为了更好地衡量,让我们添加一个方法来获取属性值:

public static object GetPropertyValue(this object obj, string propName)
{
        return obj.GetType().GetProperty(propName).GetValue (obj, null);
}

反射,基本上就是。

myObject.GetType().GetProperty(property).SetValue(myObject, "Bob", null);

或者有库在便利性和性能方面提供帮助;例如FastMember:

var wrapped = ObjectAccessor.Create(obj); 
wrapped[property] = "Bob";

(这也有一个优点,不需要提前知道它是一个字段还是一个属性)

根据MarcGravell的建议,我构造了以下静态方法。该方法一般使用FastMember将所有匹配的属性从源对象分配给目标对象

 public static void DynamicPropertySet(object source, object target)
    {
        //SOURCE
        var src_accessor = TypeAccessor.Create(source.GetType());
        if (src_accessor == null)
        {
            throw new ApplicationException("Could not create accessor!");
        }
        var src_members = src_accessor.GetMembers();
        if (src_members == null)
        {
            throw new ApplicationException("Could not fetch members!");
        }
        var src_class_members = src_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
        var src_class_propNames = src_class_members.Select(x => x.Name);
        var src_propNames = src_members.Except(src_class_members).Select(x => x.Name);

        //TARGET
        var trg_accessor = TypeAccessor.Create(target.GetType());
        if (trg_accessor == null)
        {
            throw new ApplicationException("Could not create accessor!");
        }
        var trg_members = trg_accessor.GetMembers();
        if (trg_members == null)
        {
            throw new ApplicationException("Could not create accessor!");
        }
        var trg_class_members = trg_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
        var trg_class_propNames = trg_class_members.Select(x => x.Name);
        var trg_propNames = trg_members.Except(trg_class_members).Select(x => x.Name);



        var class_propNames = trg_class_propNames.Intersect(src_class_propNames);
        var propNames = trg_propNames.Intersect(src_propNames);

        foreach (var propName in propNames)
        {
            trg_accessor[target, propName] = src_accessor[source, propName];
        }
        foreach (var member in class_propNames)
        {
            var src = src_accessor[source, member];
            var trg = trg_accessor[target, member];
            if (src != null && trg != null)
            {
                DynamicPropertySet(src, trg);
            }
        }
    }