C#内联lambda评估

Sha*_*ney 18 c# lambda

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

bool foo_equals_bar = new Func<String, bool>(str => str.Equals("foo"))("bar");
Run Code Online (Sandbox Code Playgroud)

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

bool foo_equals_bar = (str => str.Equals("foo"))("bar");
Run Code Online (Sandbox Code Playgroud)

不幸的是,这似乎不起作用.我会很高兴知道:

  1. 有没有更简单的方法来编写上面的代码行?
  2. (str => str.Equals("foo"))这样返回的是什么,可用于初始化a Func<String, bool>,但不能像a一样进行求值Func<String, bool>

我应该指出我在C#3(VS2008)中工作,所以如果解决方案只存在于C#4中,请提及.(我仍然想知道,即使目前我无法获得解决方案).

谢谢

Kon*_*hin 14

您需要一组辅助方法来使编译器推断出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");

  • @sehe:嗯,这个技巧相当广为人知,但不管怎样,谢谢.至于其他技巧,可能,现在最有用的一个叫做F#:)它比模仿函数,无点样式,模式匹配和C#中的ADT要好得多.我在C#中使用的另一个小东西是从Action委托到Func的转换器,这可以通过使lambda返回Object或特殊的Unit类型来轻松完成. (2认同)

Ada*_*kis 8

str => str == "A" 
Run Code Online (Sandbox Code Playgroud)

是相同的

delegate (string str) { return str == "A";};
Run Code Online (Sandbox Code Playgroud)

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

bool result = (str => str == "A")("B");
Run Code Online (Sandbox Code Playgroud)

编辑:

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

  • 编译器在知道str是什么类型时没有问题,问题在于推断委托类型,因为具有相同签名的委托在.NET中仍然是不同类型的. (2认同)

Dav*_*vy8 7

从(str => str.Equals("foo"))返回的内容可以用于初始化Func,但不能像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");
Run Code Online (Sandbox Code Playgroud)

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

  • +1用于提供信息(谓词&lt;&gt;被低估了) (2认同)

Dar*_*rov 5

在C#编程中的不同时间,我发现自己想定义一个lambda(或匿名委托)并在同一行中调用它。

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

在任何情况下:

bool foo_equals_bar = "bar".Equals("foo");
Run Code Online (Sandbox Code Playgroud)

*更具可读性:

bool foo_equals_bar = (str => str.Equals("foo"))("bar");
Run Code Online (Sandbox Code Playgroud)

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

  • 当然,第一行比第二行更具可读性-如果我需要的只是一个简单的均等比较,那么我不会同时使用lambda。该代码只是我所要求的一个简单示例。 (2认同)