Mel*_*sus 308 .net c# reflection properties
在C#3.5中是否有一种方法可以使用反射来设置对象属性?
例如:
MyObject obj = new MyObject();
obj.Name = "Value";
Run Code Online (Sandbox Code Playgroud)
我想obj.Name
用反思来设定.就像是:
Reflection.SetProperty(obj, "Name") = "Value";
Run Code Online (Sandbox Code Playgroud)
有办法做到这一点吗?
And*_*ndy 374
是的,你可以使用Type.InvokeMember()
:
using System.Reflection;
MyObject obj = new MyObject();
obj.GetType().InvokeMember("Name",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, obj, "Value");
Run Code Online (Sandbox Code Playgroud)
如果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);
}
Run Code Online (Sandbox Code Playgroud)
小智 273
你也可以这样做:
Type type = target.GetType();
PropertyInfo prop = type.GetProperty("propertyName");
prop.SetValue (target, propertyValue, null);
Run Code Online (Sandbox Code Playgroud)
其中target是将设置其属性的对象.
Mar*_*ell 89
反思,基本上就是
myObject.GetType().GetProperty(property).SetValue(myObject, "Bob", null);
Run Code Online (Sandbox Code Playgroud)
或者有图书馆在方便性和表现方面提供帮助; 例如FastMember:
var wrapped = ObjectAccessor.Create(obj);
wrapped[property] = "Bob";
Run Code Online (Sandbox Code Playgroud)
(这也有一个优点,就是不需要提前知道它是一个领域还是一个属性)
Eri*_* K. 26
或者你可以将Marc的一个衬里包裹在你自己的扩展类中:
public static class PropertyExtension{
public static void SetPropertyValue(this object obj, string propName, object value)
{
obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
myObject.SetPropertyValue("myProperty", "myValue");
Run Code Online (Sandbox Code Playgroud)
为了更好地衡量,我们添加一个方法来获取属性值:
public static object GetPropertyValue(this object obj, string propName)
{
return obj.GetType().GetProperty(propName).GetValue (obj, null);
}
Run Code Online (Sandbox Code Playgroud)
D S*_*ley 14
是的,使用System.Reflection
:
using System.Reflection;
...
string prop = "name";
PropertyInfo pi = myObject.GetType().GetProperty(prop);
pi.SetValue(myObject, "Bob", null);
Run Code Online (Sandbox Code Playgroud)
Ard*_*oli 13
使用这样的东西:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
要么
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);
}
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*rke 12
您还可以使用simillar方式访问字段:
var obj=new MyObject();
FieldInfo fi = obj.GetType().
GetField("Name", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(obj,value)
Run Code Online (Sandbox Code Playgroud)
使用反射,一切都可以是一本打开的书:)在我的例子中,我们绑定到私有实例级别字段.
小智 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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)