39

有没有办法在定义后立即执行 lambda 表达式?

换句话说(无效的 C# 代码):

(() => { Console.WriteLine("Hello World"); }).Invoke();
4

6 回答 6

53

当然。

new Action(() => { Console.WriteLine("Hello World"); })();

这应该够了吧。

于 2012-04-17T20:11:42.917 回答
21

另一个“选项”,它只是另外两个答案,形式略有不同:

((Action)(() => { Console.WriteLine("Hello World"); }))();

原因,直接取自 phoog 的评论

...你还没有告诉编译器你想要一个Action还是Expression<Action>. 如果您将该 lambda 表达式转换为Action您将能够对其调用 Invoke 或使用方法调用语法 () 来调用它。

不过它肯定会变得丑陋,而且我不知道这种形式在哪里有用,因为它不能用于没有名称的递归......

于 2012-04-17T20:21:47.670 回答
3

你应该能够做到这一点:

Action runMe = () => { Console.WriteLine("Hello World"); };
runMe();
于 2012-04-17T20:12:11.373 回答
3

这是一个如何使用它的示例。您希望使用无法编写为函数的几行代码的结果来初始化构造函数,因为这就是第 3 方 API 的结构。

它只是防止编写一个从未在其他任何地方调用过的独立函数的胶水代码。我用的是Func代替Action,但答案和user166390一样。

        // imagine several dozens of lines that look like this
        // where the result is the return value of a function call
        fields.Add(new ProbeField(){ 
            Command = "A",
            Field = "Average",
            Value = be.GetAverage()
        });

        // now you need something that can't be expressed as function call
        // so you wrap it in a lambda and immediately call it.
        fields.Add(new ProbeField(){ 
            Command = "C",
            Field = "Cal Coeff",
            Value = ((Func<string>)(() => {
                CalCoef coef;
                Param param;
                be.GetCalibrationCoefficients(out coef, out param);
                return coef.lowDet1.ToString();
            }))()
        });
于 2015-08-31T15:06:34.977 回答
3

对于我自己的项目,我有时会编写一个微小的可重用辅助函数,以使立即调用的 lambda 的语法看起来更短。这个“Inv”的灵感来自于 LanguageExt 库中类似的“fun”函数。

// Helper utility functions
public static void Inv(Action a) => a();
public static T Inv<T>(Func<T> f) => f();

private static void TestMethod()
{
    // Action example
    Inv(() => Console.WriteLine("Hello World!"));
    // Func example with no parameters
    bool result = Inv(() =>
    {
        if (1 == 1)
            return true;
        else
            return false;
    });
}

你也可以用一些其他的重载来扩展它,这样你就可以传入参数,但是这些在语法上看起来有点麻烦,并且可能没有那么有用。

public static Func<A, T> Inv<A, T>(Func<A, T> f) => f;
public static Func<A, B, T> Inv<A, B, T>(Func<A, B, T> f) => f;

string printNumber = Inv((int number) => $"This is the number {number}")(5);
int addedNumbers = Inv((int x, int y) => x + y)(5, 6);
于 2020-06-15T17:42:28.483 回答
0
using System.Threading.Tasks;
using System.Threading;

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

程序员真的喜欢让事情变得比他们应该做的更困难

您可以添加 500 毫秒的延迟

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

然后下一个逻辑扩展是将参数传递给您的匿名函数。您可以使用范围执行此操作:

var x=1;
Task.Run(()=>{
    x++;
});

然后你基本上可以把剩下的 C# 扔到窗外了。如果你喜欢这种函数式风格,我建议使用 JS 或 C。

于 2021-01-08T04:48:09.780 回答