Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何避免重复此集合两次?_C#_.net_Linq - Fatal编程技术网

C# 我如何避免重复此集合两次?

C# 我如何避免重复此集合两次?,c#,.net,linq,C#,.net,Linq,注意:出于保密考虑,我更改了收藏的名称 考虑以下代码: o.Flag = o2.Collection1 .Any(cpd => cpd.Collection1 .Any(plc => plc.Collection1 .Any(vd => vd.DetailedFlag))) || o2.Collection1 .Any(cpd => cpd.Collection2

注意:出于保密考虑,我更改了收藏的名称

考虑以下代码:

o.Flag =
    o2.Collection1
        .Any(cpd => cpd.Collection1
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag))) ||
    o2.Collection1
        .Any(cpd => cpd.Collection2
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag)));
很明显,我所做的是将详细标志展平为整体标志,但这段代码按原样迭代o2.Collection1两次

我看不出SelectMany可以完成这项工作,因为标志位于两个不同的集合上,即,我没有展平集合集合

我怎么能不那样做呢


注意:我觉得Jon Skeet,当我读到这篇文章时,基本上是在说我卡住了。但希望我看错了

您可以使用单个迭代直到第一层,然后分支到两个单独的查询

o.Flag =
    o2.Collection1
        .Any(cpd => cpd.Collection1
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag)) || 
             cpd.Collection2
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag)));

如果集合属于同一类型或具有定义足够信息的公共基类型,则可以在查询中简单地将它们合并:

o.Flag =
    o2.Collection1
        .Any(cpd => cpd.Collection1.Concat(cpd.Collection2)
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag)));
请注意,这里的主要优点是简化查询,减少代码重复。它不会对它的性能产生任何明显的影响

如果它们不是兼容类型,或者每个子集合的谓词之间存在细微差异(与给出的示例不同),那么您可以管理的最好方法是将两个子查询都拉入主集合的谓词中:

o.Flag =
    o2.Collection1
        .Any(cpd => cpd.Collection1
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag)) ||
            cpd.Collection2
            .Any(plc => plc.Collection1
                .Any(vd => vd.DetailedFlag)));

你就不能用var col=o2.Collection1.ToArray;//和你的LINQ查询一样,但基于col?这些看起来完全一样?@Habib,对不起。当对代码进行保密时,我把| |搞砸了。两个集合是同一类型的吗?请记住,迭代一个集合两次,或者迭代一次,但每次迭代所做的工作是相同的。避免多次迭代iterable对象的主要原因是,每次迭代时,它可能不会产生相同的信息,迭代会产生副作用,或者表示需要大量计算的内容,如DB查询。迭代一个集合没有这些问题。所以如果我理解你上面的评论,你是说因为我将低层集合连接在一起,所以我真的没有做更多的工作?好的,让我澄清一下,事实上,我用我的方法迭代了根集合两次,但是用新方法发布Concat时,它并没有产生明显的区别,对吗?它可能更安全,在您的问题的注释中解释了注意事项,但主要的是代码更简单。即使性能保持不变,这也是值得的。@MichaelPerrenoud重点是,除了重置计数器等带来的任何边际开销之外,在每次过程中迭代两次并完成一半的工作,或者迭代一次并在一次过程中完成所有的工作,这两者之间没有性能差异。@Magus是的,这绝对值得,我只是觉得你得到的东西值得一提。您这样做完全是为了提高可读性,而不是为了性能上的任何变化,因为上面提到的警告似乎不适用。第二个解决方案解决了这些问题,但没有显著提高可读性。但是,如果o2.Collection1是某种惰性可枚举的,其中项目仅在迭代时才具体化,则这将对性能产生显著影响。一个LINQ到SQL的查询之类的。