Does C# support the use of static local variables?

2019-01-22 19:10发布

Related: How do I create a static local variable in Java?


Pardon if this is a duplicate; I was pretty sure this would have been asked previously, and I looked but didn't find a dupe.

Is it possible for me to create a static local variable in C#? If so, how?

I have a static private method that is used rarely. the static method uses a Regular Expression, which I would like to initialize once, and only when necessary.

In C, I could do this with a local static variable. Can I do this in C#?

When I try to compile this code:

    private static string AppendCopyToFileName(string f)
    {
        static System.Text.RegularExpressions.Regex re =
            new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
    }

...it gives me an error:

error CS0106: The modifier 'static' is not valid for this item


If there's no local static variable, I suppose I could approximate what I want by creating a tiny new private static class, and inserting both the method and the variable (field) into the class. Like this:

public class MyClass 
{
    ...
    private static class Helper
    {
        private static readonly System.Text.RegularExpressions.Regex re =
            new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");

        internal static string AppendCopyToFileName(string f)
        {
            // use re here...
        }
    }

    // example of using the helper
    private static void Foo() 
    {
       if (File.Exists(name)) 
       {
           // helper gets JIT'd first time through this code
           string newName = Helper.AppendCopyToFileName(name);
       }
    }
    ...
}

Thinking about this more, using a helper class like this there would yield a bigger net savings in efficiency, because the Helper class would not be JIT'd or loaded unless necessary. Right?

标签: c# static
13条回答
霸刀☆藐视天下
2楼-- · 2019-01-22 19:45

What about this, since you only want it to be initialized if it's used:

private static System.Text.RegularExpressions.Regex myReg = null;
public static void myMethod()
{
    if (myReg == null)
        myReg = new Regex("\\(copy (\\d+)\\)$");
}
查看更多
你好瞎i
3楼-- · 2019-01-22 19:47

It is duplicate from Why doesn't C# support local static variables like C does?

But still, I think you will find my answer useful.

查看更多
孤傲高冷的网名
4楼-- · 2019-01-22 19:49

Three years later...

You can approximate it with a captured local variable.

 class MyNose
    {
        private static void Main()
        {
            var myNose= new MyNose();
            var nosePicker = myNose.CreatePicker();

            var x = nosePicker();
            var y = nosePicker();
            var z = nosePicker();
        }

        public Func<int> CreatePicker()
        {
            int boog = 0;

            return () => boog++;
        }
    }
查看更多
手持菜刀,她持情操
5楼-- · 2019-01-22 19:52

No, C# does not support this. You can come close with:

private static System.Text.RegularExpressions.Regex re =
         new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");

private static string AppendCopyToFileName(string f)
{

}

The only difference here is the visibility of 're'. It is exposed to the classm not just to the method.

The re variable will be initialized the first time the containing class is used in some way. So keep this in a specialized small class.

查看更多
太酷不给撩
6楼-- · 2019-01-22 19:55

Unfortunately, no. I really loved this possibility in C.

I have an idea what you could do.

Create a class that will provide access to instance-specific values, which will be preserved statically.

Something like this:

class MyStaticInt
{
    // Static storage
    private static Dictionary <string, int> staticData =
        new Dictionary <string, int> ();

    private string InstanceId
    {
        get
        {
            StackTrace st = new StackTrace ();
            StackFrame sf = st.GetFrame (2);
            MethodBase mb = sf.GetMethod ();

            return mb.DeclaringType.ToString () + "." + mb.Name;
        }
    }

    public int StaticValue
    {
        get { return staticData[InstanceId]; }

        set { staticData[InstanceId] = value; }
    }

    public MyStaticInt (int initializationValue)
    {
        if (!staticData.ContainsKey (InstanceId))
            staticData.Add (InstanceId, initializationValue);
    }
}

Can be used this way...

class Program
{
    static void Main (string[] args)
    {
        // Only one static variable is possible per Namespace.Class.Method scope
        MyStaticInt localStaticInt = new MyStaticInt (0);

        // Working with it
        localStaticInt.StaticValue = 5;
        int test = localStaticInt.StaticValue;
    }
}

It's not a perfect solution, but an interesting toy.

You can only have one static variable of this type per Namespace.Class.Method scope. Won't work in property methods - they all resolve to the same name - get_InstanceId.

查看更多
够拽才男人
7楼-- · 2019-01-22 19:57

C# doesn't support static local variables. In addition to what has been posted above, here's a link to an MSDN blog entry on the subject:
http://blogs.msdn.com/b/csharpfaq/archive/2004/05/11/why-doesn-t-c-support-static-method-variables.aspx

查看更多
登录 后发表回答