为何Linq中用OrderedEnumerable替换var无法编译?
为什么
System.Linq.OrderedEnumerable<string, string>无法直接在代码中使用? 这个问题的核心原因很直白:OrderedEnumerable<TElement, TKey>是Linq内部的实现类,它的访问权限被标记为internal,只能在自身所在的程序集内部调用,对外完全不公开。
我来拆解下具体细节:
- 当你写带
orderby的Linq查询表达式时,编译器确实会生成返回OrderedEnumerable<TElement, TKey>实例的代码,但Linq团队特意把这个类设计成内部的——他们只希望开发者依赖抽象的公共接口IOrderedEnumerable<TElement>,而非具体的实现类。这是封装原则的典型应用:这样Linq团队可以随时修改这个内部类的实现逻辑,甚至替换成完全不同的类,只要它还实现IOrderedEnumerable<TElement>,你的代码就不会受任何影响。 - 你通过
dodges.GetType()看到的完全限定名,是运行时这个实例的真实类型名称,但编译阶段,你的代码所在程序集没有权限访问这个内部类型,所以编译器会报错提示找不到它。 - 而
IOrderedEnumerable<TElement>是公开接口,它定义了排序后序列必须支持的所有行为(比如后续的ThenBy/ThenByDescending操作),这才是Linq设计时希望我们直接使用的类型。
回到你的代码,正确的写法应该用公共接口声明变量:
IOrderedEnumerable<string> dodges = from someCars in myCars where someCars.Contains("Dodge") orderby someCars descending select someCars;
当然,更推荐的是继续用var——在Linq场景下,我们通常不需要关心序列的具体实现类型,只需要调用它提供的接口方法(比如ToList()、foreach遍历等),var能让代码更简洁,也完全符合Linq的设计意图。
这种“用内部类实现公共接口,对外只暴露接口”的模式在.NET生态里非常普遍,目的就是为了保持API的稳定性,同时给框架开发者留足优化和修改的空间。
内容的提问来源于stack exchange,提问作者David Klempfner
相关产品推荐
相关产品推荐

