Я думаю, что ваша оригинальная версия в конечном итоге установит значение "на один уровень слишком глубоко".
Я думаю, что рекурсивный шаблон будет легче следовать и потребовать меньше кода.Вот быстрая версия, которую я написал вместе, которая работает на простых тестовых примерах.
Существует несколько возможностей для оптимизации (перестройка строки в рекурсивном вызове) и в крайних случаях (например, 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";
}
Она дает следующие результаты: