Вы можете сделать это с помощью отражения:
void SetObjectProperty(object theObject, string propertyName, object value)
{
Type type=theObject.GetType();
var property=type.GetProperty(propertyName);
var setter=property.SetMethod();
setter.Invoke(theObject, new ojbject[]{value});
}
ПРИМЕЧАНИЕ. Обработка ошибок намеренно оставлена для удобства чтения.
Решение mquander можно немного улучшить, чтобы уменьшить дублирование. Вы можете использовать тот факт, что вы можете передать в null
элемент в содержимом конструктора XElement, и он будет проигнорирован. Поэтому мы можем переместить условие дальше в:
Func<ErrorType, XElement> recursiveGenerator = null;
recursiveGenerator = (error => new XElement(error.Name,
outputTagsOnly ? null : new XAttribute("Ignore", error.Filter),
error.ChildErrors.Select(recursiveGenerator));
var element = new XElement("ErrorList", ChildErrors.Select(recursiveGenerator));
Вы можете попытаться разделить вашу проблему на две разные:
Затем код будет выглядеть так:
private XElement ErrorListToXml(ErrorList el, bool outputTagsOnly)
{
// Need to declare in advance to call within the lambda.
Func<ErrorType, XElement> treeGenerator = null;
Func<ErrorType, object[]> elementParametersGenerator = null;
treeGenerator = error => new XElement
(error.Name,
elementParametersGenerator(error));
if(outputTagsOnly)
elementParametersGenerator = error =>
new object[] {error.ChildErrors.Select(treeGenerator)};
else
elementParametersGenerator = error =>
new object[] { new XAttribute("Ignore", error.Filter), error.ChildErrors.Select(treeGenerator) };
var element = new XElement
("ErrorList",
ChildErrors.Select(treeGenerator));
Console.WriteLine(element);
return element;
}
Не намного лучше в данном конкретном случае, но это более общий подход.
Вы можете безопасно переместить оператор «if» внутри лямбда-функции, если хотите:
Func<ErrorType, XElement> recursiveGenerator = null;
recursiveGenerator = (error =>
outputTagsOnly
? new XElement(error.Name,
error.ChildErrors.Select(recursiveGenerator));
: new XElement(error.Name, new XAttribute("Ignore", error.Filter),
error.ChildErrors.Select(recursiveGenerator)));
var element = new XElement("ErrorList", ChildErrors.Select(recursiveGenerator));
Кроме этого, похоже, нет никакого тривиального способа упростить то, что вы ' у меня есть.
(PS Когда он выглядит некрасиво, нанеси немного помады на эту свинью, красиво распечатав ее;)
Думаю, вы можете это сделать, но, в конце концов, это все еще if:
recursiveGenerator = error => outputTagsOnly ?
new XElement(error.Name,error.ChildErrors.Select(recursiveGenerator)
:
new XElement(error.Name,new XAttribute("Ignore", error.Filter),
error.ChildErrors.Select(recursiveGenerator);
Вы можете довольно легко выбрать между значениями одного типа в лямбде:
customer => flag ? customer.Name : customer.Address
Вы можете использовать оператор if в лямбде, приложив немного больше усилий:
customer =>
{
if (flag)
return customer.Name
else
return customer.Address
}
Ни один из это очень помогает вашему методу.