51

Can you have a static variable in a static method? Would the value of this variable be preserved across all calls to the method?

eg.

public static void MyMethod()
{
    static int x = 0;
    x++;
}
Lance U. Matthews
  • 15,725
  • 6
  • 48
  • 68
Craig Johnston
  • 757
  • 2
  • 8
  • 9
  • Are you asking because you've used a `Shared` local variable before in VB.NET? This isn't natively supported by the CLR in any case, and VB.NET has to use some behind-the-scenes trickery to create this effect. – Cody Gray - on strike Dec 24 '10 at 10:15
  • 2
    What you need is a static class member – David Heffernan Dec 24 '10 at 10:16
  • 1
    @Colin - I think he wants x to be only accessible by MyMethod(), and not by any other methods regardless of whether they are in this class or not. – blizpasta Dec 24 '10 at 10:20
  • possible duplicate of [Does C# support the use of static local variables?](http://stackoverflow.com/questions/2393156/does-c-sharp-support-the-use-of-static-local-variables) – nawfal Jan 12 '14 at 21:13
  • Anyone know if this has changed in 7 years. I vaguely recall that this either newly is, or potentially might be a new feature. – RLH Jan 10 '17 at 15:21

3 Answers3

51

No.

You can't have local static variables.

From MSDN:

C# does not support static local variables (variables that are declared in method scope).

And here:

The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.

As you can see, local variables are not mentioned.


You can, however use a static field:

public class MyClass
{
    private static int MyVariable = 10;

    public static void MyMethod()
    {
        MyVariable++;
    }
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 39
    Unfortunate because if `MyVariable` is only used in `MyMethod` it belongs in `MyMethod`, not exposed to the rest of the class. – AustinWBryan Jun 06 '18 at 10:25
  • 2
    This is probably the single disadvantage of using C# in favor of an older "C" language. C++ scoping was weaker, but you could have local static variables. This is what make the `strtok` function even possible. From the POSIX strtok page: This function uses static storage to keep track of the current string position between calls. I wrote a variant of it in C++ that ignored empty records and accepted any delimiter that could be represented by a C++ String class. Knowing how these things work should make it replicate-able in any language, but alas, this is one weakness of C#. – Joel Trauger Jun 22 '18 at 20:11
  • 3
    @JoelTrauger How exactly does C++ have weaker scoping rules than C#? As far as I can tell, they are identical, except that C++ may have local static variables. – Clearer Sep 26 '18 at 06:49
  • IIRC, in C++ you have explicitly invoke inheritance to gain the properties of a class. Anything not explicitly passed forward through inheritance is automatically private. In C#, just make the class public and you automatically inherit all the public members of that class. C# also allows for internal scoping to further control the scoping of a class member. Because of that I consider C++ scoping to be weaker, though others might find it stronger...since static variables do not exist in C#. – Joel Trauger Oct 15 '18 at 16:02
11

No, but you could have:

private static int x = 0;
public static void MyMethod()
{
     x++;
} 
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Grhm
  • 6,726
  • 4
  • 40
  • 64
  • I think you will mostly want `[ThreadStatic]private static int x = 0;` if you do that? – Chris F Carroll Oct 11 '21 at 17:27
  • the issue is that it is likely in this kind of thing that you don't want x accessed directly by other parts of the class. I'm sure the answer would be "well just wrap everything in a static class then" But that seems like a lot of boilerplate. – matt Feb 11 '22 at 02:51
0

Here is sort of a hackish way to accomplish what you're trying to do. Turn MyMethod into an Action that creates a closure on x. The variable x will only be visible to the innermost delegate, and behaves like a static variable. If anyone has any suggestions for improving this pattern let me know.

public static readonly Action MyMethod = new Func<Action>(delegate ()
{
    var x = 0;
    return delegate () { x++; };
}).Invoke();

//example usage:
public void Init() {
    MyMethod();
}
user3163495
  • 2,425
  • 2
  • 26
  • 43