C# 跨方法调用保留局部变量

C# 跨方法调用保留局部变量,c#,C#,在C#中有没有办法让一个方法在不同的调用中保留一个变量?例如: private void foo() { int j; //declare this so as it isn't destroyed with the stack frame. int i = calculateSomeValue() + j; j = i; } 我通常会使用这样的成员变量: private int j = 0; private void foo() { int i = calcu

在C#中有没有办法让一个方法在不同的调用中保留一个变量?例如:

private void foo()
{
    int j; //declare this so as it isn't destroyed with the stack frame.
    int i = calculateSomeValue() + j;
    j = i;
}
我通常会使用这样的成员变量:

private int j = 0;
private void foo()
{
    int i = calculateSomeValue() + j;
    j = i;
}
我不喜欢在类的所有其他方法中如何访问变量
j
。另外,这样做看起来很麻烦:定义一个成员变量时,它将只在一个方法中使用,以跟踪上次调用该方法时
i
的值


这可能是一种好的/干净的方式吗?或者我应该仅仅使用成员变量的方式而忘记它吗?

我认为没有其他方式可以给出您所要求的范围。在这种情况下,其他方法可以访问
j
,作为成员变量,这是您使用的OOP概念的直接结果,这些概念将成员封装在holder对象中

因此,我将继续使用member变量,而不担心其他方法能够访问它。如果出于某种原因,你必须避免访问变量的其他方法,也许你应该考虑重构在自己的类型,虽然可能与给定的例子是不合理的。
希望这有帮助。

您可以使用一个小小的嵌套类来封装它,大致如下:

public class Test
{
    private int foo()
    {
        return nested.foo();
    }

    private int calculateSomeValue()
    {
        return 42;
    }

    readonly Nested nested = new Nested();

    private class Nested
    {
        private int j;

        public int foo()
        {
            int i = calculateSomeValue() + j;
            j = i;
        }
    }
}

外部类中的方法只能访问嵌套的
的公共成员,因此它们只能访问
foo()
。在本例中,
j
是不可访问的。但是请注意,
Nested
中的方法可以访问外部类的所有私有成员。

在C中,使用静态局部变量可以实现这一点

void foo()
{
     static int j;
     int i = calculateSomeValue() + j;
     j = i;
}
在C#中,故意不包括此功能

你有几个选择,这取决于j的预期寿命。如果您只是在连续调用中需要它,并且出于某种原因不想使用循环,那么可以使用递归方法

private void foo()
{
    foo(0);
}

private void foo(int j)
{
    int i = calculateSomeValue() + j;
    foo(j);
}
如果您想要更多的控制或更长的生命周期,面向对象的方法是将此功能推送到一个类上,该类可以是普通类或私有类,并嵌套在现有类中

public class ParentClass()
{
    FooClass bar = new FooClass();

    private class FooClass()
    {
        private int j = 0;
        public void foo()
        {
            int i = calculateSomeValue() + j;
            j = i;
        }

        private int calculateSomeValue()
        {
            //
        }
    }

    private void DoStuff()
    {
        bar.foo();
    }
}

此外,我建议重新权衡是否值得首先保护变量。

使用闭包是一种很糟糕的方法。但这意味着您必须将您的方法定义为匿名函数,并将它们包装在定义它们的某个全局方法中。认为这是一个学术演习,绝对不是一个生产解决方案。对于现实生活中的解决方案,绝对要考虑一个单独的类。

static void Main(string[] args)
{
    var j = 0;

    Func<int> calculateSomeValue = () =>
    {
        return 41;
    };

    Action myFoo = () =>
    {
        int i = calculateSomeValue() + j;
        j = i;
    };
}
static void Main(字符串[]args)
{
var j=0;
Func calculateSomeValue=()=>
{
返回41;
};
动作myFoo=()=>
{
int i=CalculateMeValue()+j;
j=i;
};
}

我认为没有一种方法可以在不将j类定义为类字段(或属性)的情况下给出它的作用域。感兴趣的是看看是否有人知道另一种方法。如果你有其他方法不感兴趣的状态,你可能想考虑这是否值得一个单独的类型。但一般来说,不,您应该绝对有一个实例变量。这是对象状态的一部分。听起来像是一个试图退出的迷你类。为什么不创建一个只有那个变量和函数的类呢?如果变量需要“保护”,这可能是最佳做法。在C#中不可能。您只能在VB.Net中使用声明来执行此操作。为什么这比使用简单的实例变量更好?每当我们想在字段中保留一些值时,我们是否应该引入一个新类?@Fabjan OP说,该变量不能被该类的其他方法访问是很重要的。@Fabjan我通常不会为这样简单的代码费心,但它可以很好地扩展到稍微复杂一些的代码,您可以在其中封装一些行为,但它并不复杂到应该引入一个全新的非嵌套类。然而,在现实中,类通常应该足够小,这样的事情永远不会吸引人。@MatthewWatson好吧,这确实是一段很好的代码,但在我看来,对于它所处理的任务来说,这似乎有点过火了。但这不一样:C中的静态局部与该类的所有实例共享。C中的字段是每个实例的独立的。C没有类(虽然静态基本上是全局范围),也许C++需要更仔细,但我在那里没有经验。不管怎样,我发布的两个C#方法都将包含在类的范围内。