Если оператор в функции Лямбды?

Вы можете сделать это с помощью отражения:

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});
}

ПРИМЕЧАНИЕ. Обработка ошибок намеренно оставлена ​​для удобства чтения.

5
задан Chris 3 June 2009 в 13:55
поделиться

5 ответов

Решение 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));
6
ответ дан 18 December 2019 в 09:10
поделиться

Вы можете попытаться разделить вашу проблему на две разные:

  1. Как построить дерево из структуры ошибок.
  2. Что поместить в узлы дерева.

Затем код будет выглядеть так:

        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;
        }

Не намного лучше в данном конкретном случае, но это более общий подход.

0
ответ дан 18 December 2019 в 09:10
поделиться

Вы можете безопасно переместить оператор «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 Когда он выглядит некрасиво, нанеси немного помады на эту свинью, красиво распечатав ее;)

6
ответ дан 18 December 2019 в 09:10
поделиться

Думаю, вы можете это сделать, но, в конце концов, это все еще 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);
0
ответ дан 18 December 2019 в 09:10
поделиться

Вы можете довольно легко выбрать между значениями одного типа в лямбде:

customer => flag ? customer.Name : customer.Address

Вы можете использовать оператор if в лямбде, приложив немного больше усилий:

customer =>
{
  if (flag)
    return customer.Name
  else
    return customer.Address
}

Ни один из это очень помогает вашему методу.

6
ответ дан 18 December 2019 в 09:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: