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查询并且不要求我写它或者是其他什么呢?
类型推断过程有点复杂; 有关详细信息,请参阅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
| 归档时间: |
|
| 查看次数: |
238 次 |
| 最近记录: |