为什么以下泛型方法调用不需要类型?

Wil*_*Wil 2 c# generics syntax lambda

对不起 - 不确定一个更好的名字,请修改,如果你能想到更好.

我正在尝试学习更多关于IEnumerable/collections/generics的内容,我想我到了某个地方,直到这个例子让我:

 var nums = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10 };

 var result = FilterNums(nums, i => i % 2 != 0);
Run Code Online (Sandbox Code Playgroud)

.....

public static IEnumerable<T1> FilterNums<T1>(IEnumerable<T1> numslist, Func<T1, bool> predicateDelegate)
Run Code Online (Sandbox Code Playgroud)

.....

为什么呼叫呼叫FilterNums工作?如果我将其更改为FilterNums<int>,它仍然有效,这就是我实际期望输入的内容.

那么,是否有一些如何检测T1lambda查询并且不要求我写它或者是其他什么呢?

Eri*_*ert 8

类型推断过程有点复杂; 有关详细信息,请参阅C#规范的第7章.

简而言之就是这样的.

当您调用没有通用参数列表的方法时,首先我们创建一组该名称的所有可访问方法.

接下来我们检查一下它们是否是通用的.如果它们是,那么我们试图查看是否可以从实际参数推断泛型类型参数.推理过程是这样的.假设你有一个参数列表A:

A: (nums, i => i%2 != 0)
Run Code Online (Sandbox Code Playgroud)

和一个形式参数类型列表P:

P: (IEnumerable<T1>, Func<T1, bool>)
Run Code Online (Sandbox Code Playgroud)

和一组泛型类型参数X:

X: <T1>
Run Code Online (Sandbox Code Playgroud)

类型推断的目标是从A的每个成员推断到P的相应成员,以便推导出关于X的每个成员的足够信息.

这个特殊问题很容易.从第一个参数我们看到nums的类型是int [].我们看到P中的第一个形式参数是IEnumerable<T1>.我们知道int []可以转换为IEnumerable<int>,因此T1可能是int.我们记下这个事实.

在这一点上,我们基本上完成了.我们没有关于T1的信息,我们可以从第二个参数/参数对推断出来.类型推断成功,并确定T1为int.所以我们假装你用它<int>作为类型参数列表来调用它.

这是一个非常简单的类型推断问题.考虑一下这个:

A: (customers, c=>c.Name)
P: (IEnumerable<T>, Func<T, R>)
X: <T, R>
Run Code Online (Sandbox Code Playgroud)

这是你遇到的问题customers.Select(c=>c.Name).

我们做什么?从第一个论点我们推断出"客户实施IEnumerable<Customer>,因此T可能是客户". 在进行了扣除,我们可以说"lambda中的c因此是Customer.因此,这是来自Customer的lambda,无论Customer.Name的类型是什么.这是字符串.因此R是字符串".

看看在这种情况下如何将一个推理链接到下一个; 我们不能简单地"并行"进行推理,因为一个推论可能取决于另一个推论的结果.这些依赖项可以包含循环和其他奇怪的拓扑.我们如何通过这种依赖链进展的确切细节有点复杂; 请参阅规格了解详情.

我们还必须处理为类型参数推导出两个或更多边界的情况,以及这些边界是"上","下"还是"精确".

如果这个主题让你感兴趣,我已经广泛地写了这篇文章.看到

http://blogs.msdn.com/b/ericlippert/archive/tags/type+inference/

关于类型推断的各个方面的许多文章,而不仅仅是泛型方法类型推断.有关我解释方法类型推断如何在C#3.0中工作的视频,请参阅:

http://wm.microsoft.com/ms/msdn/visualcsharp/eric_lippert_2006_11/EricLippert01.wmv


Lin*_*ron 6

这是因为类型推断.

编译器理解您正在发送一个int,因此它隐式地将泛型类型设置为int.如果您将查看intellisense,您将看到您的泛型类型设置为int.