惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
S
Securelist
D
Docker
The Register - Security
The Register - Security
GbyAI
GbyAI
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
罗磊的独立博客
博客园 - 【当耐特】
F
Full Disclosure
WordPress大学
WordPress大学
腾讯CDC
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
SecWiki News
SecWiki News
L
Lohrmann on Cybersecurity
I
InfoQ
MyScale Blog
MyScale Blog
量子位
Cyberwarzone
Cyberwarzone
博客园 - 三生石上(FineUI控件)
The Hacker News
The Hacker News
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
博客园_首页
H
Help Net Security
K
Kaspersky official blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
Blog — PlanetScale
Blog — PlanetScale
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
The Cloudflare Blog
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
爱范儿
爱范儿
P
Privacy International News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
The GitHub Blog
The GitHub Blog
C
Cybersecurity and Infrastructure Security Agency CISA
B
Blog RSS Feed

博客园 - cp

HR:.Net(Senior)Software Engineer/Project Leader IT Consulting Positions (Senior Level) Software Sales Engineer / Software Engineer Scott Gu上海见面会 有个朋友公司急召C++程序员 对比面向对象和面向服务 预告一下接下来要写的心得 C# 3.0 规范(PDC2005)中文word版本 C#3.0规范(七)对象以及集合构造者 关于ComponentArt Web.UI 2006.1(build 1208)源代码之若干说明 ComponentArt Web.UI 2006.1 源代码 C#3.0规范(六)重载决断 C#3.0规范(四)Lambda 表达式 C#3.0规范(三)扩展函数 C#3.0(二)隐式类型化的本地变量 C#3.0规范(一)C#3.0概述 IIS不工作 Const n = 234234245# [导入]一个使用的小问题
C#3.0规范(五)类型推断
cp · 2006-05-14 · via 博客园 - cp
 

26.1.1 Type inference 类型推断

When a generic method is called without specifying type arguments, a type inference process attempts to infer type arguments for the call. Lambda expressions passed as arguments to the generic method participate in this type inference process.

当不使用特定类型的参数调用一个泛型函数时,类型推断会尝试为此次调用推断参数类型。Lambda表达式传递参数到泛型函数,且参与这次类型推断的过程。

As described in §20.6.4, type inference first occurs independently for each argument. In this initial phase, nothing is inferred from arguments that are lambda expressions. However, following the initial phase, additional inferences are made from lambda expressions using an iterative process. Specifically, inferences are made as long as one or more arguments exist for which all of the following are true:

§20.6.4所描述的那样,类型推断首先发生在每个独立的参数中。在初始化的阶段,如果参数是lambda表达式,那么什么也不推断。然而,紧跟着初始化阶段,额外的推断将被做出,这是使用一个迭代的过程所完成的。尤其是,只要下列条件为真,那么一或多个参数的推断就会被做出:

·         The argument is a lambda expression, in the following called L, from which no inferences have yet been made.

·         参数是一个lambda表达式,下称L,并且还没有被推断过类型。

·         The corresponding parameter’s type, in the following called P, is a delegate type with a return type that involves one or more method type parameters.

·         相应的参数类型,下称P,是一个代理类型并且具有一个返回值,而该返回值关联一或多个函数类型参数。

·         P and L have the same number of parameters, and each parameter in P has the same modifiers as the corresponding parameter in L, or no modifiers if L has an implicitly typed parameter list.

·         P L 具有相同数量的参数,并且每个在P中的参数具有相同的修饰符,就如同相应的L的参数,或者可以没有修饰符,如果L具有一个隐式类型的参数列表。

·         P’s parameter types involve no method type parameters or involve only method type parameters for which a consistent set of inferences have already been made.

·         P的参数类型没有参与函数类型参数或者仅参与的函数类型参数是为了一套一致的,已经被做出的推断。

·         If L has an explicitly typed parameter list, when inferred types are substituted for method type parameters in P, each parameter in P has the same type as the the corresponding parameter in L.

·         如果L具有显式类型参数列表,且当推断的类型作为P的函数类型参数的替代品时,每个P中的参数具有相同的,和相应的L中的参数一样的类型。

·         If L has an implicitly typed parameter list, when inferred types are substituted for method type parameters in P and the resulting parameter types are given to the parameters of L, the body of L is a valid expression or statement block.

·         如果L具有一个隐式的参数列表,且当推断的类型作为P的函数类型参数的替代品并且结果参数类型已经由L的参数所给于时,L的主体是一个确实的表达式或者声明块。

·         A return type can be inferred for L, as described below.

·         能够为L的返回类型进行推断,如上所述。

For each such argument, inferences are made from that argument by relating the return type of P with the inferred return type of L and the new inferences are added to the accumulated set of inferences. This process is repeated until no further inferences can be made.

对于每个这样的参数,推断是从参数做出的,这个过程是通过相关联的P的返回类型以及推断的L的返回类型实现的,并且,新的推断会加入到一套已经积累完毕的推断中。这个过程重复到没有推断可以被做出。

For purposes of type inference and overload resolution, the inferred return type of a lambda expression L is determined as follows:

类型推断和重载决断的目的是为了,某个lambda表达式L的推断类型如下而决定的:

·         If the body of L is an expression, the type of that expression is the inferred return type of L.

·         如果L的主体是一个表达式,那么表达式的类型是从L的返回类型所推断的。

·         If the body of L is a statement block, if the set formed by the types of the expressions in the block’s return statements contains exactly one type to which each type in the set is implicitly convertible, and if that type is not the null type, then that type is the inferred return type of L.

·         如果L的主体是一个声明块,且如果这套由表达式类型格式化的在该声明块中的返回声明包含确实的一种类型,并且这套类型中每个类型都是可以被隐式转换的,再且那类型不为null类型,那么类型可以从L的返回类型所推断的。

·         Otherwise, a return type cannot be inferred for L.

·         相反的,则返回类型不能够由L推断做出。

As an example of type inference involving lambda expressions, consider the Select extension method declared in the System.Query.Sequence class:

作为一个包含lambda表达式的类型推断的例子,考虑Select这个扩展函数,它被声明在 System.Query.Sequence类中:

namespace System.Query
{
public static class Sequence
{
    public static IEnumerable<S> Select<T,S>(
         this IEnumerable<T> source,
       Func<T,S> selector)
    {
       foreach (T element in source) yield return selector(element);
    }
}
}

Assuming the System.Query namespace was imported with a using clause, and given a class Customer with a Name property of type string, the Select method can be used to select the names of a list of customers:

假设System.Query名称空间是通过using语句导入的,并且给于了一个名为Customer的类,该类具有一个类型为stringName属性,Select函数可以被使用作为选择一组客户名字中的某个:

List<Customer> customers = GetCustomerList();
IEnumerable<string> names = customers.Select(c => c.Name);

The extension method invocation (§26.2.3) of Select is processed by rewriting the invocation to a static method invocation:

Select的扩展函数调用26.2.3)是通过重写掉用为static函数掉用来处理的:

IEnumerable<string> names = Sequence.Select(customers, c => c.Name);

Since type arguments were not explicitly specified, type inference is used to infer the type arguments. First, the customers argument is related to the source parameter, inferring T to be Customer. Then, using the lambda expression type inference process described above, c is given type Customer, and the expression c.Name is related to the return type of the selector parameter, inferring S to be string. Thus, the invocation is equivalent to

既然类型参数没有被显式指定,那么,只有使用类型推断来推导该类型参数。首先,customers的参数关联到源参数,推断TCustomer。接着,使用lambda表达式类型推断进行处理,如上所述,c 被给于Customer类型,并且表达式c.Name关联于一个select语句的返回类型参数,推断Sstring。那么,该调用相等于

Sequence.Select<Customer,string>(customers, (Customer c) => c.Name)

and the result is of type IEnumerable<string>.

并且结果的类型为IEnumerable<string>.

The following example demonstrates how lambda expression type inference allows type information to “flow” between arguments in a generic method invocation. Given the method

下列例子展示了怎么样使用lambda表达式类型推断以便允许类型信息能够“跟随”在参数中,该情况出现在一个泛型函数的调用中。给于的函数为

static Z F<X,Y,Z>(X value, Func<X,Y> f1, Func<Y,Z> f2) {
return f2(f1(value));
}

type inference for the invocation

为该调用所作的类型推断

double seconds = F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalSeconds);

proceeds as follows: First, the argument "1:15:30" is related to the value parameter, inferring X to be string. Then, the parameter of the first lambda expression, s, is given the inferred type string, and the expression TimeSpan.Parse(s) is related to the return type of f1, inferring Y to be System.TimeSpan. Finally, the parameter of the second lambda expression, t, is given the inferred type System.TimeSpan, and the expression t.TotalSeconds is related to the return type of f2, inferring Z to be double. Thus, the result of the invocation is of type double.

过程如下:首先,参数"1:15:30"关联于值参,推断Xstring。那么,第一个lambda表达式的参数s推断类型为string,并且TimeSpan.Parse(s)表达式关联于f1的返回类型,推断YSystem.TimeSpan类型。最后,第二个lambda表达式的参数t,给于得推断类型为System.TimeSpan,并且t.TotalSeconds表达式关联于f2的返回类型,推断Zdouble类型。那么,该调用的结果类型为 double