I am new to C# LINQ. This is a general basic question on how to use IntelliSense to use LINQ effectively. I am working on a small piece of code to find the average file size in a folder. The following lines are part of the code.
string[] dirfiles = Directory.GetFiles("c:\\orderprocessing\\");
var avg = dirfiles.Select(file => new FileInfo(file).Length).Average();
This code works fine and I got it from a website. If I have to write it by myself, I am wondering how to find out what to pass to the Select() method. When I hover over it, the IntelliSense shows the following:
IEnumerable<TResult> IEnumerable<string, TResult>(Func<string, TResult>
selector) (+ 1 overload)
I want to know how to read this suggestion and come up with file => new FileInfo(file).Length to pass to the method? Sorry if the question is very basic!
An expression like
x => expression using x
or
(x, y, ...) => expression using x, y, ...
Is called a Lambda expression. It is a very concise way of writing a method to be used as a delegate right where you need it. You can think of a delegate as a function pointer that you can pass as parameter to another method.
The two expressions from above translate to
resultType HiddenMethodName(parameterType x)
{
return expression using x;
}
or
resultType HiddenMethodName(parameterType1 x, parameterType2 y, ...)
{
return expression using x, y, ...;
}
The point is that the types are inferred by the C# compiler. E.g. you only write file => ... and C# knows that file is an input parameter of type string, since you called Select on an array of string.
Func<string, TResult> selector
means that you must pass it a function with a string input parameter. The result type is the generic type TResult.
The Intellisense information ...
IEnumerable<TResult> IEnumerable<string>.Select<string, TResult>(
Func<string, TResult> selector)
... has the structure ...
ReturnType InputType.ExtensionMethod<InputElementType, ResultElementType>(
function delegate that transforms input to output)
... and means that we have an Enumerable<string>: the array string[] dirfiles. On this input enumeration we apply the extension method Select (after the dot).
Select<string, TResult> expects an input enumeration of type IEnumerable<string> and returns an output enumeration of type IEnumerable<TResult> (this is the return type you see at the beginning). The type TResult is unknown at this stage, as it depends on what your lambda expression returns.
The point of this Select extension method is to convert an input enumeration to an output enumeration (possibly) of another type. The transformation of each element of the input enumeration is performed by the delegate Func<string, TResult> selector (given as lambda expression).
Your lambda expression file => new FileInfo(file).Length has a string input parameter file and returns a result of type long (the file length given as a 64 bit integer). .Average() transforms the resulting IEnumerable<long> to a double.
In addition to the links provided by @BasilKosovan, you might also have a look at Generics (C# Programming Guide) (that's the thing with the angle brackets <>).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With