Linq“选择”理智问题

时间:2011-04-27 13:37:11

标签: c# linq

我的逻辑类似于下面的代码。好像为了检查这样的空引用,我必须有两个单独的Select语句。 linq忍者可以告诉我这样的查询可以改进吗?

List<C> cList = Globals.GetReferences(irrelevantThing) // GetReferences returns List<A>, which are references to B
            .Select(a => a.GetB()) // GetB returns type B, can be null
            .Where(b => b != null && someOtherConditions)
            .Select(c => new C(b)) // C Constructor cannot have a null parameter
            .ToList();

谢谢。

编辑:稍微清理一下示例代码。

2 个答案:

答案 0 :(得分:5)

好吧,首先我要更改参数名称 - 在第一个Select之后,你有一个B,那么为什么不把它称为b

List<B> bList = Globals.GetReferences(irrelevantThing)
            .Select(a => a.GetB()) // GetB returns type B, can be null
            .Where(b => b != null && someOtherConditions)
            .Select(b => new B(b))
            .ToList();

那时候,我不得不想知道为什么你有第二个Select ...你已经有了B,所以你为什么要创建一个新的? B(B old)构造函数做了什么?

如果你需要另一个选择,那对我来说似乎没问题。我的意思是,如果GetB便宜,你可以随时使用:

List<B> bList = Globals.GetReferences(irrelevantThing)
            .Where(a => a.GetB() != null && someOtherConditions)
            .Select(a => new B(a.GetB()))
            .ToList();

......但是老实说我不确定。

答案 1 :(得分:2)

我发现使用查询语法和let运算符看起来稍微好一些:

   var queryB = from a in Globals.GetReferences(irrelevantThing)
                let b = a.GetB()
                where b != null && someOtherConditions
                select new B(b);

   var bList = queryB.ToList()

取决于您的偏好......

FYI在扩展方法语法中,上面转换为

   var queryB = Globals.GetReferences(irrelevantThing)
            .Select(a => new { a, b = a.GetB() })
            .Where(x => x.b != null && someOtherConditions)
            .Select(x => new B(x.b))
            .ToList();

更新:刚才意识到您还可以使用select into子句从字面上翻译确切的原始查询:

   var queryB = from a in Globals.GetReferences(irrelevantThing)
                select a.GetB() into b
                where b != null && someOtherConditions
                select new B(b);

仍然喜欢let但是......