代码之家  ›  专栏  ›  技术社区  ›  Chris

lambda函数中的if语句?

  •  4
  • Chris  · 技术社区  · 15 年前

    这也许很简单,但我对lambda还比较陌生,所以请耐心等待。

    我有一个函数使用lambda函数来递归。 主函数接收一个bool,告诉它是否在lambda中包含某些信息。

    这个函数被设计成将自定义类编写成XML——我认为代码是相当自我解释的。

    目前,我已经用一个简单的if语句克服了这个问题,但感觉很难看,所以想知道是否有人知道更好的方法?

            private XElement ErrorListToXml(ErrorList el, bool outputTagsOnly)
        {
            // Need to declare in advance to call within the lambda.
            Func<ErrorType, XElement> recursiveGenerator = null;
    
            if (outputTagsOnly)
                recursiveGenerator = error => new XElement
                    (error.Name,
                     error.ChildErrors.Select(recursiveGenerator));
            else
                recursiveGenerator = error => new XElement
              (error.Name,
              new XAttribute("Ignore", error.Filter),
               error.ChildErrors.Select(recursiveGenerator));
    
    
            var element = new XElement
                       ("ErrorList",
                        ChildErrors.Select(recursiveGenerator));
    
            Console.WriteLine(element);
    
            return element;
        }
    
    5 回复  |  直到 15 年前
        1
  •  6
  •   Jon Skeet    15 年前

    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));
    
        2
  •  6
  •   mqp    15 年前

    如果您愿意,可以在lambda函数中安全地移动“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));
    

    除此之外,似乎没有任何简单的方法来简化你所拥有的。

    (P.S.当它看起来很难看时,给它印上一些唇膏。)

        3
  •  6
  •   Amy B    15 年前

    您可以很容易地在lambda中决定相同类型的值:

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

    您可以在lambda中使用if语句,只需稍加努力:

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

    这两种方法对你的方法都没有很大帮助。

        4
  •  0
  •   BFree    15 年前

    我想你可以这样做,但到今天为止,如果:

                    recursiveGenerator = error => outputTagsOnly ? 
                       new XElement(error.Name,error.ChildErrors.Select(recursiveGenerator)
                  : 
                  new XElement(error.Name,new XAttribute("Ignore", error.Filter), 
                 error.ChildErrors.Select(recursiveGenerator);
    
        5
  •  0
  •   Massimiliano    15 年前

    您可以尝试将问题分解为两个不同的问题:

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

    在这个特定的案例中没有明显的好转,但这是一种更为普遍的方法。