C# LINQ“查询语法”是否支持Duck类型?
关于LINQ查询语法C# LINQ“查询语法”是否支持Duck类型?,c#,.net,linq,duck-typing,linq-query-syntax,C#,.net,Linq,Duck Typing,Linq Query Syntax,关于LINQ查询语法 var foo = new List<int> { 1, 2 }; var boo = from n in foo where n > 1 select n; …我一直认为这种语法是正确的。至少在我了解IQueryable之前。也许也可以观察到。但我最近注意到一个建议。直到我找到了一个专门的网站,这个故事才显得非常有说服力。LINQtoTasks看起来完全依赖于查询语法 好吧,这是怎么回事?查询语法是否使
var foo = new List<int> { 1, 2 };
var boo = from n in foo
where n > 1
select n;
…我一直认为这种语法是正确的。至少在我了解IQueryable之前。也许也可以观察到。但我最近注意到一个建议。直到我找到了一个专门的网站,这个故事才显得非常有说服力。LINQtoTasks看起来完全依赖于查询语法
好吧,这是怎么回事?查询语法是否使用duck类型?当我自己试一试时,这确实有效,并且似乎证明了这一切都是关于duck类型的,而不是IEnumerable:
public class Joker<T>
{
public T Item;
public Joker(T item)
{
Item = item;
}
}
public static class JokerHelp
{
public static T2 Select<T,T2>(this Joker<T> joke, Func<T,T2> call)
{
return call(joke.Item);
}
}
var oof = new Joker<int>(5);
int foo = from a in oof
select a;
如果duck类型是查询语法的工作方式(显然是这种情况),那么关于这一点的官方MSDN文档在哪里?或者任何合理的文档?您缺少的是实现IEnumerable的列表。因此,我一直认为这种语法仅限于在IEnumerable上操作,从技术上讲,这是正确的,尽管是以一种有限的方式。IQueryable还实现了IEnumerable,以及IList和数组。因此,您可以对任何实现IEnumerable的对象执行linq查询 因为Joker没有实现IEnumerable,所以您的查询尝试将失败。Select、Where等扩展方法是围绕IEnumerable构建的。所以,如果你想从oof中选择,你只需要更新你对小丑的定义
编辑:答案在最初格式化的问题的上下文中有一定的意义。编辑后的问题使我的回答过时了C中有一些特性,编译器进行结构类型匹配,而不是名义类型匹配。示例包括foreach循环、查询理解语法、select、where等以及wait/async。对于所有这些特性,编译器实际上只是寻找具有特定名称的方法,而不是特定的接口或类 这些特性没有绑定到特定接口的原因是为了尽可能地将语言与.NET framework实现解耦。我想这会被认为是duck类型的一种形式 Eric Lippert更透彻地解释了该功能和推理
我注意到,这些特性通常是错误的或不完整的。编辑了我的帖子,代码在没有涉及IEnumerable的情况下运行。想想看,哇,怎么样。也许编译器在运行时得到了super-reflection-y,只是从一个in-oof转换来为传入的类型找到一个Select扩展方法,然后它就可以工作了?绝对没想到。迷人。没有运行时反射…只是简单的老鸭子打字。阅读我链接的维基百科文章:有一阵子了。Eric Lippert的文章仍然可以在这里找到:
public class Joker<T> : IEnumerable<T>
{
// (actually implement IEnumerable<T> functionality
}