Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this MSDN example for Func<> delegate have a superfluous Select() call?

Tags:

c#

delegates

msdn

The MSDN gives this code example in the article on the Func Generic Delegate:

Func<String, int, bool> predicate = ( str, index) => str.Length == index;

String[] words = { "orange", "apple", "Article", "elephant", "star", "and" };
IEnumerable<String> aWords = words.Where(predicate).Select(str => str);

foreach (String word in aWords)
    Console.WriteLine(word);

I understand what all this is doing. What I don't understand is the

Select(str => str)

bit. Surely that's not needed? If you leave it out and just have

IEnumerable<String> aWords = words.Where(predicate);

then you still get an IEnumerable back that contains the same results, and the code prints the same thing.

Am I missing something, or is the example misleading?

like image 524
TarkaDaal Avatar asked Apr 25 '10 15:04

TarkaDaal


People also ask

What is Func <> C#?

A Func in C# is a way to define a method in-line that has a return value. There is a similar concept of an Action that doesn't have a return value, but we'll get to that in a sec. The return value's type is always the last generic parameter on the Func 's definition.

What is the difference between func string string and delegate?

Func is a generic delegate included in the System namespace. It has zero or more input parameters and one out parameter. The last parameter is considered as an out parameter. This delegate can point to a method that takes up to 16 Parameters and returns a value.

What is the delegate type called when a value is returned?

TResult. The type of the return value of the method that this delegate encapsulates. This type parameter is covariant.

Which of the delegate type can be used if we want to pass maximum input parameters without having any output parameter?

Action delegate can contain a maximum of 16 input parameters and does not have any return type.


2 Answers

The Select is indeed redundant.

I suspect that this example may have been "translated" from the query comprehension syntax, as in:

IEnumerable<String> aWords = 
    from w in words
    where (...)
    select w;

When using this syntax, you have to select at the end, it's just how the compiler works. When using the Where extension method, however, it's completely unnecessary unless you actually need to do a separate projection.

Or, maybe it's just a mistake. The MSDN writers aren't infallible!

like image 169
Aaronaught Avatar answered Oct 27 '22 20:10

Aaronaught


No it's not needed.

Such a construct could be used if you wanted to force a sequence to be lazily evaluated i.e. to prevent casting. If you had a method that returned a List<T> but declared an IEnumerable<T> return type then a client could cast the return type and manipulate the underlying list directly. Obviously this is a very bad idea, but a class could protect its state by applying an identity select such as the one used in this example:

public IEnumerable<T> Items
{
   get { return privateList.Select(i => i); }
}
like image 1
Lee Avatar answered Oct 27 '22 21:10

Lee