当前位置:  开发笔记 > 编程语言 > 正文

使用反射设置对象属性

如何解决《使用反射设置对象属性》经验,为你挑选了8个好方法。

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

例如:

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

我想obj.Name用反思来设定.就像是:

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

有办法做到这一点吗?



1> Andy..:

是的,你可以使用Type.InvokeMember():

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


如果你没有处理所有字符串,你可能首先要转换数据:`var val = Convert.ChangeType(propValue,propInfo.PropertyType);`source:http://www.devx.com/vb2themax/Tip/19599
或者,您可以使用`obj.GetType().GetProperty("Name")?. GetSetMethod()?. Invoke(...)`

2> 小智..:

你也可以这样做:

Type type = target.GetType();

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

prop.SetValue (target, propertyValue, null);

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


我今天也做了同样的事情.以上工作很好,显然在尝试使用之前应该对prop进行空检查.
@AntonyScott我认为你想知道你是否在调用错误的属性,所以"默默地失败"似乎是一个糟糕的过程.

3> Marc Gravell..:

反思,基本上就是

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

或者有图书馆在方便性和表现方面提供帮助; 例如FastMember:

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

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



4> Erik K...:

或者你可以将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);
}



5> D Stanley..:

是的,使用System.Reflection:

using System.Reflection;

...

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



6> Ardalan Shah..:

使用这样的东西:

public static class PropertyExtension{       

   public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
   {
    PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
    property.SetValue(p_object, Convert.ChangeType(value, property.PropertyType), null);
   }
}

要么

public static class PropertyExtension{       

   public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
   {
    PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
    Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
    object safeValue = (value == null) ? null : Convert.ChangeType(value, t);

    property.SetValue(p_object, safeValue, null);
   }
}



7> JoshBerke..:

您还可以使用simillar方式访问字段:

var obj=new MyObject();
FieldInfo fi = obj.GetType().
  GetField("Name", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(obj,value)

使用反射,一切都可以是一本打开的书:)在我的例子中,我们绑定到私有实例级别字段.



8> 小智..:

当您想使用属性名称从另一个对象大量分配Object的属性时,可以尝试这样做:

public static void Assign(this object destination, object source)
    {
        if (destination is IEnumerable && source is IEnumerable)
        {
            var dest_enumerator = (destination as IEnumerable).GetEnumerator();
            var src_enumerator = (source as IEnumerable).GetEnumerator();
            while (dest_enumerator.MoveNext() && src_enumerator.MoveNext())
                dest_enumerator.Current.Assign(src_enumerator.Current);
        }
        else
        {
            var destProperties = destination.GetType().GetProperties();
            foreach (var sourceProperty in source.GetType().GetProperties())
            {
                foreach (var destProperty in destProperties)
                {
                    if (destProperty.Name == sourceProperty.Name && destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
                    {
                        destProperty.SetValue(destination,     sourceProperty.GetValue(source, new object[] { }), new object[] { });
                        break;
            }
        }
    }
}


嗨,欢迎来到Stack Overflow.请正确格式化您的代码,而不是将其转储到您的帖子中,它将帮助其他人理解您的答案.
推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有