C#中的局部静态变量是什么?

4

受JavaScript闭包的启发,我尝试使用Func<>委托在C#中模拟局部静态变量...以下是我的代码。

public Func<int> Increment()
    {
        int num = 0;
        return new Func<int>(() =>
        {
            return ++num;
        });
    }

Func<int> inc = Increment();
Console.WriteLine(inc());//Prints 1
Console.WriteLine(inc());//Prints 2
Console.WriteLine(inc());//Prints 3

我想知道是否有其他方法在C#中模拟本地静态变量?

谢谢。


8
在C#中创建静态变量的方法是实际上创建一个带有静态成员的类。这感觉就像你在问“我如何让C#表现得像Javascript?” 我认为答案应该是“不要这样做”。它们是两种不同的语言,强制其中一种像另一种一样行事只会带来悲伤的结果。 - Matt Burland
4
它以什么方式表现得像一个“static”变量?“static”变量属于,而这个变量属于实例。它绝对不是等同于一个“static”变量。 - James
5
没错,但他想要模仿 C++ 中的函数作用域静态变量,就像这样:function() { static int = 0; .. } - antiduh
4
好的,我现在实际上明白正在被问什么了。对于那些感到困惑的人,请参见https://dev59.com/7nNA5IYBdhLWcg3wNq8y和AlfredBr的答案。 - Ben Aaronson
4
我不认为这是那个问题的复制,它询问的是不同的内容并且可能的答案也不同。 - Ben Aaronson
显示剩余21条评论
1个回答

5

这绝对是可怕的,但一种方法是使用迭代器方法并丢弃输出。例如,如果你想:

public void PrintNextNumber()
{
    static int i = 0; //Can't do this in C#
    Console.Out.WriteLine(i++);
}

你可以改写成:

public IEnumerator<object> PrintNextNumber()
{
    int i = 0;
    while (true)
    {
        Console.Out.WriteLine(i++);
        yield return null;
    }
}

那么,你不再调用PrintNextNumber(),而是执行var printNext = PrintNextNumber(); printNext.MoveNext;

我写这个答案只是为了满足好奇心,我绝对不建议真的这样做!

如果你想从方法中返回一些东西,那么情况会变得更加复杂,但这是可行的-你可以使用yield return,然后在调用MoveNext之后使用Current来检索它。


1
这并不使值“静态”。PrintNextNumber().MoveNext将始终打印出“0”,因为每次调用PrintNextNumber时都会创建一个新的枚举器。实际上获得所需行为的唯一方法是将枚举器存储在静态变量中,以便公共方法可以返回它或获取其下一个值,这当然违反了不具有静态字段的要求。 - Servy
不错,@BenAaronson :) - Uthaiah
@Servy 不使用静态字段的目的并不是因为 OP 对 static 关键字有厌恶感,而是为了避免将变量暴露给比它更大的范围。因此,具有静态成员字段引用该方法并没有同样的问题。 - Ben Aaronson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接