Lambda expressions (how is the extension function Select defined?)
var numbers=new int[]{1,2,3};
va开发者_如何学JAVAr numbers1=numbers.Select(n=>n);
var numbers2=numbers.Select(n=>n.ToString());
var numbers3=numbers.Select(n=>new {Number=n, Even=n%2==0});
How is it possible for the output of extension function SELECT to be of any type?
It is a generic extension method defined with the following signature:
public static IEnumerable<Tresult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector);
With the type information present in the source and selector argument, the compiler can infer the types used so you don't need to explicitly name it.
The particular version of Select
here takes a Func<T, TResult>
selector, where T
is the type of the input (in this case, int
), and TResult
is the output. Based upon your lambda expression, the compiler is able to infer the types of TResult
. In your case, the types are
- int
- string
- Anonymous
If you are curious about such anonymous functions, I encourage to you to check out the C# 4.0 language specification, perhaps starting at section 7.15.
IEnumerable.Select
is a generic method with these signatures:
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector
)
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, int, TResult> selector
)
The function passed in must return a TResult
and the Select
itself returns IEnumerable<TResult>
. The type of TResult
can be deduced by the compiler (as done in the post), or it can be explicitly annotated.
More information about generics -- how TResult
can be "an arbitrary but particular type", for instance -- can be found at the C# Generics Programming Guide. There are a number of SO questions that discuss the limits of C# type inference (including that of generics) as well.
Happy coding.
精彩评论