C#内联lambda评估

时间:2011-01-21 16:58:45

标签: c# lambda

在使用C#进行编程的不同时间,我发现自己处于需要定义lambda(或匿名委托)并在同一行中调用它的情况。在这一点上,我能够做到这一点的“最干净”的方式是这样的:

bool foo_equals_bar = new Func<String, bool>(str => str.Equals("foo"))("bar");

我希望能够写下以下内容:

bool foo_equals_bar = (str => str.Equals("foo"))("bar");

不幸的是,这似乎不起作用。我很想知道:

  1. 是否有更简单的方法来编写上面的代码行?
  2. (str => str.Equals("foo"))返回的内容可用于初始化Func<String, bool>,但无法像Func<String, bool>那样进行评估?
  3. 我应该指出我在C#3(VS2008)工作,所以如果解决方案只存在于C#4中,请提及。 (我仍然想知道,即使目前我无法获得解决方案)。

    由于

6 个答案:

答案 0 :(得分:11)

您需要一组辅助方法来使编译器推断出lambda类型,例如:


public static class Functional
{
    public static Func<TResult> Lambda<TResult>(Func<TResult> func)
    {
        return func;
    }

    public static Func<T, TResult> Lambda<T, TResult>(Func<T, TResult> func)
    {
        return func;
    }

    public static Func<T1, T2, TResult> Lambda<T1, T2, TResult>(Func<T1, T2, TResult> func)
    {
        return func;
    }
}

现在你可以写:


bool foo_equals_bar = Functional.Lambda(str => str.Equals("foo"))("bar");

答案 1 :(得分:8)

str => str == "A" 

相同
delegate (string str) { return str == "A";};

所以不,没有办法只获得lambda,因为如果你刚才说编译器不知道str是什么类型

bool result = (str => str == "A")("B");

编辑:

是的,您可以向lambda表达式添加类型,例如(string str) => str == "A";但是,由于某种原因,它们不能隐式。不知道为什么。感谢Yuriy的评论。

答案 2 :(得分:6)

  

从(str =&gt;)返回什么   str.Equals(“foo”))就是这样   用于初始化Func,但不能像a一样进行评估   FUNC?

只需使用内置类型即可:

Expression<Func<string, bool>> a = str => str.Equals("foo");
Expression<Predicate<string>> b = str => str.Equals("foo");
Expression<Action<string>> c = str => str.Equals("foo");
Func<string, bool> a1 = str => str.Equals("foo");
Predicate<string> b1 = str => str.Equals("foo");
Action<string> c1 = str => str.Equals("foo");

所有这些都是lambda表达式的有效解释。这就是我能想到的内置类型。还有任何与签名匹配的代表。

答案 3 :(得分:4)

  

在编程时的不同时间   C#我发现自己陷入困境   在哪里我想定义一个lambda(或   匿名代表)并在其中调用它   同一行。

那些是奇怪的情况。避免他们。这是不可能的,因为编译器无法推断出类型。当您将匿名委托传递给编译器可以推断出类型的某个方法时,这可能会起作用。

在任何情况下:

bool foo_equals_bar = "bar".Equals("foo");

*

更具可读性
bool foo_equals_bar = (str => str.Equals("foo"))("bar");

*假设这样的语法是可能的

答案 4 :(得分:0)

您必须将lambda转换为func或委托
((Func<string, bool>)(str => str.Equals("bar")))("baz")

答案 5 :(得分:0)

using System.Threading.Tasks;
using System.Threading;

Task.Run(()=>{
     //do something
});

您可以添加 500 毫秒的延迟

Task.Run(()=>{
    Thread.Sleep(500);
    //do something
});

不确定 MS 何时添加它,但它不是 C#3

这种编程风格可以完成任何事情,一旦你学会了这一点,你基本上可以忽略其余的 C# 规范