我需要动态设置属性值
我读了这个Get property value from string using reflection in C#
并使用以下代码获取值
public Object GetPropValue(Object obj, String name) {
foreach (String part in name.Split('.')) {
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
现在我需要将值设置为具有相同属性名称
的其他对象Employee emp1=new Employee();
var city=GetPropValue(emp1, "Address.City");
Need to set this city to other employee. Here Address is other class
emp1.GetType().GetProperty("Address.City").SetValue(emp2,city,null) //always sets null
但这不是设定。我如何制作一个通用的setter方法来简化这项工作?
答案 0 :(得分:2)
这一行不正确:
emp2.Address.City= emp1.GetType().GetProperty("Address.City").SetValue(emp2,city,null)
您正尝试将emp2.Address.City
设置为在给定对象上调用属性的setter的结果。
在这种情况下,你为什么要使用反射?根据您的代码行,您只需编写
即可emp2.Address.City = city;
因为您的反射代码也设置了emp2
的属性。因此即使它起作用,它也会做两次相同的事情。
您的代码就像写作一样:
emp2.Address.City = city;
emp1.GetType().GetProperty("Address.City").SetValue(emp2,city,null);
答案 1 :(得分:-1)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace LinqTests
{
class Program
{
static void Main(string[] args)
{
var f1 = new F1 { F2 = new F2 { Name = "Test"}, Q = 10 };
var f3 = new F3 { F2 = new F2() };
Copier.Copy(f1, f3, "Q");
Copier.Copy(f1, f3, "F2.Name");
}
static class Copier
{
public static void Copy(object source, object destination, string navigationPath)
{
var sourceValuePointHandle = GetValuePointHandle(source, navigationPath);
var destinationValuePointHandle = GetValuePointHandle(destination, navigationPath);
destinationValuePointHandle.SetValue(sourceValuePointHandle.GetValue());
}
private static ValuePointHandle GetValuePointHandle(object instance, string navigationPath)
{
var propertyName = new String(navigationPath.TakeWhile(x => x != '.').ToArray());
var property = instance.GetType().GetProperty(propertyName);
if (propertyName.Length != navigationPath.Length)
{
var propertyInstance = property.GetValue(instance, null);
return GetValuePointHandle(propertyInstance, navigationPath.Substring(propertyName.Length + 1, navigationPath.Length - propertyName.Length - 1));
}
else
return new ValuePointHandle(instance, property);
}
class ValuePointHandle
{
public object Instance
{
get;
private set;
}
public PropertyInfo Property
{
get;
private set;
}
public ValuePointHandle(object instance, PropertyInfo property)
{
Instance = instance;
Property = property;
}
public void SetValue(object value)
{
Property.SetValue(Instance, value, null);
}
public object GetValue()
{
return Property.GetValue(Instance, null);
}
}
}
class F1
{
public int Q
{
get;
set;
}
public F2 F2
{
get;
set;
}
}
class F2
{
public string Name
{
get;
set;
}
}
class F3
{
public int Q
{
get;
set;
}
public F2 F2
{
get;
set;
}
}
}
}