Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ“查询语法”是否支持Duck类型?_C#_.net_Linq_Duck Typing_Linq Query Syntax - Fatal编程技术网

C# LINQ“查询语法”是否支持Duck类型?

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看起来完全依赖于查询语法 好吧,这是怎么回事?查询语法是否使

关于LINQ查询语法

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
}