2 回答
TA贡献1850条经验 获得超11个赞
我认为您的原始版本最终会将值设置为“太深一层”。
我认为递归模式更容易遵循,并且需要更少的代码。这是我整理的一个快速版本,适用于简单的测试用例。
有几个优化机会(在递归调用中重建字符串)和边缘情况(如null检查),我现在没有时间处理,但我认为它们不会太难添加。
public void SetProperty(object target, string property, object setTo)
{
var parts = property.Split('.');
var prop = target.GetType().GetProperty(parts[0]);
if (parts.Length == 1)
{
// last property
prop.SetValue(target, setTo, null);
}
else
{
// Not at the end, go recursive
var value = prop.GetValue(target);
SetProperty(value, string.Join(".", parts.Skip(1)), setTo);
}
}
这是一个 LINQPad 演示,展示了它的实际效果:
void Main()
{
var value = new A();
Debug.WriteLine("Original value:");
value.Dump();
Debug.WriteLine("Changed value:");
SetProperty(value, "B.C.D","changed!");
value.Dump();
}
public void SetProperty(object target, string property, object setTo)
{...}
public class A
{
public B B { get; set; } = new B();
}
public class B
{
public C C { get; set; } = new C();
}
public class C
{
public string D { get; set; } = "test";
}
它产生以下结果:
TA贡献1942条经验 获得超3个赞
我想完成答案Bradley Uffner
public void SetProperty (object target, string property, object setTo)
{
var parts = property.Split ('.');
// if target object is List and target object no end target -
// we need cast to IList and get value by index
if (target.GetType ().Namespace == "System.Collections.Generic"
&& parts.Length != 1)
{
var targetList = (IList) target;
var value = targetList[int.Parse (parts.First ())];
SetProperty (value, string.Join (".", parts.Skip (1)), setTo);
}
else
{
var prop = target.GetType ().GetProperty (parts[0]);
if (parts.Length == 1)
{
// last property
prop.SetValue (target, setTo, null);
}
else
{
// Not at the end, go recursive
var value = prop.GetValue (target);
SetProperty (value, string.Join (".", parts.Skip (1)), setTo);
}
}
}
- 2 回答
- 0 关注
- 121 浏览
添加回答
举报