C#LINQ和func

时间:2015-03-15 03:47:38

标签: c# linq lambda func

这是我正在使用的简化版本,只是为了让您知道我正在努力实现的目标:

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);
}

是否可以使标有(*)的线更短?因为当我尝试删除冗余(在我看来)代理创建时,它会给出错误:

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

但它不应该给出错误,很明显返回的类型是什么......

2 个答案:

答案 0 :(得分:4)

Lambda表达式是无类型的。这就是为什么你必须添加编译器一些信息来确定它的类型(通过给它们一些上下文)。

  

请注意,lambda表达式本身没有类型,因为公共类型系统没有&#34; lambda表达式的内在概念。&#34; 但是,有时说话方便非正式的&#34;类型&#34;一个lambda表达式。在这些情况下,类型引用lambda表达式转换为的委托类型或表达式类型。

     

来自Lambda Expressions (C# Programming Guide)

您可以根据您将其分配给的变量/参数/属性/字段的类型来执行此操作:

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

或将其投射给代表:

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

这是必要的,因为您可以想象将自己的委托声明为

public delegate int MyDelegate();

编译器如何知道您的匿名类型属性是应该键入MyDelegate还是Func<int>

答案 1 :(得分:2)

你可以缩短整个事情:

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

但您仍然需要明确转换为Func<int>

唯一的另一种方式是:

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);
}