Lambda 函数中的 if 语句?

发布于 2024-07-22 20:25:57 字数 1042 浏览 6 评论 0原文

这可能很简单,但我对 Lambda 还很陌生,所以请耐心等待。

我有一个使用 Lambda 函数进行递归的函数。 main 函数接收一个 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;
    }

This may be quite simple but I'm rather new to Lambda's so bear with me.

I have a function that uses a Lambda function to recurse.
The main function receives a bool telling it to include certain information or not within the lambda.

The function is designed to write out a custom class to XML - I think the code is pretty self explanitory.

At the moment I have overcome the problem using a simple if statement, but it feels ugly so wondered if anyone knew a better way?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

白衬杉格子梦 2024-07-29 20:25:57

mquander 的解决方案可以稍微改进以减少重复。 您可以利用以下事实:您可以在 XElement 构造函数内容中传入 null 元素,并且该元素会被忽略。 因此,我们可以进一步将条件移至:

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

mquander's solution can be improved slightly to reduce duplication. You can use the fact that you can pass in null an element in the XElement constructor content, and it gets ignored. We can therefore move the condition further in:

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));
揽清风入怀 2024-07-29 20:25:57

您可以非常轻松地在 lambda 中相同类型的值之间做出决定:

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

您可以在 lambda 中使用 if 语句,但需要花费更多的精力:

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

这些都对您的方法没有太大帮助。

You can make a decision between values of the same type in a lambda pretty easily:

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

You can use an if statement in a lambda with a little more effort:

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

Neither of these helps your method greatly.

回忆那么伤 2024-07-29 20:25:57

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

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

在这种特殊情况下并没有明显更好,但它是一种更通用的方法。

You can try to decompose your problem into two different ones:

  1. How to build a tree from errors structure.
  2. What to put into the tree nodes.

Then the code will look like:

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

Not any significantly better in this particular case, but it's a more general approach.

南城旧梦 2024-07-29 20:25:57

如果您愿意,您可以安全地在 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));

除此之外,似乎没有任何简单的方法可以简化您所拥有的内容。

(PS:当它看起来很丑的时候,通过漂亮的印刷给那只猪涂上口红;)

You could move the "if" statement inside the lambda function safely, if you preferred:

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

Other than that, there doesn't seem to be any trivial way to simplify what you've got.

(P.S. When it looks ugly, put some lipstick on that pig by pretty-printing it ;)

淤浪 2024-07-29 20:25:57

我想你可以做到这一点,但最终它仍然是一个如果:

                recursiveGenerator = error => outputTagsOnly ? 
                   new XElement(error.Name,error.ChildErrors.Select(recursiveGenerator)
              : 
              new XElement(error.Name,new XAttribute("Ignore", error.Filter), 
             error.ChildErrors.Select(recursiveGenerator);

I guess you can do this, but end of the day it's still an 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文