Linq投影如何在扩展方法和查询表达式之间工作

时间:2016-06-20 09:42:03

标签: c# linq

摆弄Linq,令我惊讶的是我遇到了以下情况:

var words = new List<string>() {"seven", "ten", "one" ,"five"};

var test1 = words.OrderBy(w => w.Length);
var test2 = words.OrderBy(w => w.Lenght).Select(w => w);
var test3 = from w in words
            orderby w.Length
            select w;

VS调试告诉我

test1: System.Linq.IOrderedEnumerable<string>
test2: System.Collections.Generic.IEnumerable<string>
test3: System.Linq.IOrderedEnumerable<string>

我期待test2test3的相同类型,哦,男孩!,编译器或其他任何东西,不这么认为。

  1. 任何人都可以解决问题吗?
  2. 此外,有什么情况我会更喜欢test2而不是test1,只要我投射到同一类型?即Select(w => w)

1 个答案:

答案 0 :(得分:3)

当查询表达式的Select子句中没有真正的转换时,编译器忽略了对select的调用。这就是test1test3中的查询相同的原因。

我的回答是基于Jon Skeet博客的这篇文章(阅读查询表达式段落): LINQ to Objects

var result = from x in source
                 where x < 4
                 select x; 
  

(...)我们实际上并没有进行真正的转型。在这种情况下 - 只要查询中还有其他内容,在这种情况下我们的&#34;其中&#34;子句 - 编译器有效地省略了&#34; select&#34;条款(...)

关于问题的第二部分,当您最后调用Select时,您将获得IEnumerable<T>,因为Select返回的是IOrderedEnumerable<T>IEnumerable<T>扩展IOrderedEnumerable<T>,因此通过在最后进行投射,您将失去使用 static _createPossibleOptionsFromStackAbleImages (stackAbleImages) { let result = []; console.log(ConfiguratorPreLoads._makePossibleCombinations([], stackAbleImages[0], stackAbleImages, 0)); return result; } static _makePossibleCombinations (previous, current, all, index, result = []) { //All possible options are checked if (index === all.length) { return result; } //Init state if (previous[0] === undefined) { current.forEach((currentValue) => { result.push(currentValue); }); ++index; return ConfiguratorPreLoads._makePossibleCombinations(result, all[index], all, index, result); } //The array is empty or we are done if (current === undefined || current[0] === undefined) { ++index; return ConfiguratorPreLoads._makePossibleCombinations(previous, all[index], all, index, result); } //Remember the combinedPreviousValues so we can build new one from them let combinedPrevious = []; previous.forEach((previousValue) => { current.forEach((currentValue) => { combinedPrevious.push(`${previousValue}_${currentValue}`); result.push(`${previousValue}_${currentValue}`); }); }); index++; //Recursion return ConfiguratorPreLoads._makePossibleCombinations(combinedPrevious, all[index], all, index, result); } 界面成员的能力。