ebvtrnog
ebvtrnog

Reputation: 4377

C# LINQ and func

This is a simplified version of what I am using, just to let you know of what I'm trying to accomplish:

public Dictionary<int, Func<int>> Magic(Dictionary<int, int> dictionary)
{
    return dictionary
        .Select(v => new
        {
            key = v.Key,
            function = new Func<int>(() => v.Value + 5)   // *
        })
        .ToDictionary(v => v.key, v => v.function);
}

Is it possible to make the line marked with (*) shorter? Because when I try to remove redundant (in my opinion) delegate creation, it is giving errors:

function = () => v.Value + 5   // *

But it shouldn't give errors, it is clear what the returned type is...

Upvotes: 2

Views: 1388

Answers (2)

Enigmativity
Enigmativity

Reputation: 117055

You can shorten the whole thing to this:

public Dictionary<int, Func<int>> Magic(Dictionary<int, int> dictionary)
{
    return dictionary
        .ToDictionary(v => v.Key, v => (Func<int>)(() => v.Value + 5));
}

But you still need to explicitly cast to Func<int>.

The only other way is this:

public Dictionary<int, Func<int>> Magic(Dictionary<int, int> dictionary)
{
    return dictionary
        .ToDictionary<KeyValuePair<int, int>, int, Func<int>>(
            v => v.Key, 
            v => () => v.Value + 5);
}

Upvotes: 2

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

Lambda expressions are typeless. That's why you have to add compiler some information to determine it's type (by giving them some context).

Note that lambda expressions in themselves do not have a type because the common type system has no intrinsic concept of "lambda expression." However, it is sometimes convenient to speak informally of the "type" of a lambda expression. In these cases the type refers to the delegate type or Expression type to which the lambda expression is converted.

from Lambda Expressions (C# Programming Guide)

You can either do it by the type of variable/parameter/property/field you're assigning it to:

Func<int> func = () => 5;

or by casting it to a delegate:

var func = (Func<int>)(() => 5);

It's necessary because you can imagine having your own delegate declared as

public delegate int MyDelegate();

How would the compiler know if your anonymous type property should be typed as MyDelegate or Func<int>?

Upvotes: 5

Related Questions