我可以使用LINQ有条件地创建IEnumerable吗?

cod*_*nix 2 .net c# linq collections

我必须遵循以下代码:

List<Obj> coll = new List<Obj>();

if (cond1) coll.Add(new Obj { /*...*/ });
if (cond2) coll.Add(new Obj { /*...*/ });
if (cond3) coll.Add(new Obj { /*...*/ });
Run Code Online (Sandbox Code Playgroud)

有没有办法使用LINQ或集合初始化器?

编辑:

我想在这里使用集合初始化器的原因是因为我有一个对象树,我用initialiers和LINQ完全初始化.这个地方是唯一一个不遵循这一原则的地方.

var myobj = new MyBigObj 
{
    Prop1 = from .. select ..,
    Prop2 = from .. select ..,
    ...
    Prop3 = new MySmallerObj 
    {
      PropSmall1 = from .. select ..,
      PropSmall2 = from .. select ..,
      ...
    }
};
Run Code Online (Sandbox Code Playgroud)

而现在这根本不适合我的计划:

List<Obj> coll = new List<Obj>();

if (cond1) coll.Add(new Obj { /*...*/ });
if (cond2) coll.Add(new Obj { /*...*/ });
if (cond3) coll.Add(new Obj { /*...*/ });

myobj.Prop4 = coll;
Run Code Online (Sandbox Code Playgroud)

当然,我可以把这个代码放在一个单独的函数,返回IEnumerable并调用.. :)

EDIT2:

看起来我必须编写一些扩展方法,我会称之为:

new Obj[0]
.ConditionalConcat(cond1, x=>new Obj { /*...*/ })
.ConditionalConcat(cond2, x=>new Obj { /*...*/ })
.ConditionalConcat(cond3, x=>new Obj { /*...*/ })
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

一个相当可怕的选择:

var conditions = new[] { cond1, cond2, cond3 };
var values = new[] { new Obj {...}, // First value
                     new Obj {...}, // Second value
                     new Obj { ...} // Third value
                   };

var list = conditions.Zip(values, (condition, value) => new { condition, value })
                     .Where(pair => pair.condition)
                     .Select(pair => pair.value)
                     .ToList();
Run Code Online (Sandbox Code Playgroud)

它并不比原始代码简单得多;)(并且它也无条件地创建所有值 - 它只是有条件地将它们包含在集合中.)

编辑:一种替代方案,它只在需要时构造值:

var conditions = new[] { cond1, cond2, cond3 };
var valueProviders = new Func<Obj>[] { 
    () => new Obj {...}, // First value
    () => new Obj {...}, // Second value
    () => new Obj { ...} // Third value
};


var list = conditions.Zip(valueProviders,
                          (condition, provider) => new { condition, provider })
                     .Where(pair => pair.condition)
                     .Select(pair => pair.provider())
                     .ToList();
Run Code Online (Sandbox Code Playgroud)

编辑:根据您的语法,这是一个相当容易的选择:

new List<Obj>()
    .ConditionalConcat(cond1, x=>new Obj { /*...*/ })
    .ConditionalConcat(cond2, x=>new Obj { /*...*/ })
    .ConditionalConcat(cond3, x=>new Obj { /*...*/ })
Run Code Online (Sandbox Code Playgroud)

使用扩展方法:

public static List<T> ConditionalConcat<T>(this List<T> source,
                                           bool condition,
                                           Func<T> provider)
{
    if (condition)
    {
        source.Add(provider);
    }
    return source;
}
Run Code Online (Sandbox Code Playgroud)