在创建时调用lambda

本文关键字:lambda 调用 创建 | 更新日期: 2023-09-27 18:15:33

在javascript中,使用闭包并创建然后立即调用匿名函数是很常见的,如下所示:

var counter = (function() {
    var n = 0;
    return function() { return n++; }
}());

由于强类型,c#中非常冗长:

Func<int> counter = ((Func<Func<int>>)(() =>
{
    int n = 0;
    return () => n++;
}))();
在c#中是否有更优雅的方法来处理这种类型的事情?

在创建时调用lambda

在c#中不需要外部lambda,它可以被一个简单的块替换。

直接调用lambda是Javascript中缺少块级变量的一种解决方案(新版本支持使用let的块作用域)。

Func<int> counter;
{
     int n = 0;
     counter = () => n++;
}

我唯一能建议的是Func<int> counter可能是var counter,但不能想到其他任何东西。注意,counter仍然是强类型的。


参见:var

没有更好的方法,但是转换有点令人困惑,所以我更喜欢这样:

Func<int> counter = new Func<Func<int>>(() => { var n = 0; return () => n++; })();

编辑:正如CodeInChaos刚才所问的,外部lambda似乎是多余的。

编辑2:不,这不是多余的,因为你想要一个n的闭包。所以要么用上面的方法,要么:
Func<Func<int>> counter = () => { var n = 0; return () => n++; };
int x = counter()();

编辑3:因为我不确定你是否想重用计数器函数,这样它就可以被重新初始化,你想要两种场景(或另一种场景)中的哪一种:

            Func<Func<int>> counter0 = () => { var n = 0; return () => n++; };
        Console.WriteLine("Counter0:");
        var count0 = counter0();
        for (var i = 0; i < 5; i++)
        {
            Console.WriteLine(count0());
        }
        var count1 = counter0();
        for (var i = 0; i < 5; i++)
        {
            Console.WriteLine(count1());
        }
        Console.WriteLine("Counter1:");
        Func<int> counter1 = new Func<Func<int>>(() => { var n = 0; return () => n++; })();
        for (var i = 0; i < 5; i++)
        {
            Console.WriteLine(counter1());
        }
        for (var i = 0; i < 5; i++)
        {
            Console.WriteLine(counter1());
        }

输出:Counter0:0123.40123.4Counter1:0123.456789

真的需要强制转换吗?这取决于你如何使用这个函数。

可以简单地像

这样做
Func<int> counter = () => { int n; return n++;}

这看起来有点奇怪,虽然,在函数中声明变量,我很确定这不是你真正想要的。