tags:

views:

634

answers:

4

In VB.Net, I can declare a variable in a function as Static, like this:

Function EncodeForXml(ByVal data As String) As String
    Static badAmpersand As Regex = new Regex("&(?![a-zA-Z]{2,6};|#[0-9]{2,4};)")

    data = badAmpersand.Replace(data, "&")

    ''// more processing

    return data
End Function

Note that I need to use the keyword Static, rather than Shared, which is the normal way to express this in VB.Net. How can I do this in C#? I can't find its equivalent.

+4  A: 

There is no equivalent in C# unfortunately.

You will need to use a class level variable.

This is one of the few things that VB has that I wish C# had.

Max Schmeling
+13  A: 

Ha! In posting the question, I found the answer! Rather than googling for C# I should have been looking for details on how VB.Net implements it, and typing up the question made that apparent to me. After applying that insight, I found this:
http://weblogs.asp.net/psteele/articles/7717.aspx

That article explains that it's not really supported by the CLR, and the VB compiler creates a static (shared) variable "under the hood" in the method's class. To do the same in C#, I have to create the variable myself.

More than that, it uses the Monitor class to make sure the static member is thread-safe as well. Nice.

As a side note: I'd expect to see this in C# sometime soon. The general tactic I've observed from MS is that it doesn't like VB.Net and C# to get too far apart feature-wise. If one language has a feature not supported by the other it tends to become a priority for the language team for the next version.

Joel Coehoorn
And to think, I was going to pimp my own blog (where I addressed this a couple months ago) ... But you've saved me the trouble, and that entry is considerably more clear than my own. Thanks for the link!
John Rudy
You can also check out the IL/C# code generated from VB using reflector, I notice that sometime ago. It's also fun to see what some VB tricks are possible done in C#
faulty
+6  A: 

Personally I'm glad that C# doesn't have this. Logically, methods don't have state: types and instances do. C# makes that logical model clearer, IMO.

Jon Skeet
Agreed that using this to save state with a method is a bad idea. Note that in this case the purpose is to make sure the creation/compilation of the regex happen only once. You could say this is a form of state, but I think here it's really about performance, not keeping data between method calls.
Joel Coehoorn
In that case it's fine just to be a static readonly field. It's a piece of immutable state associated with the type, initialized when the type is initialized. Make sense as a static to me :)
Jon Skeet
I take it you haven't worked with Closures yet. They literally are mutable state being stored in a method.
Jonathan Allen
Yes, I certainly have worked with closures - but I regard those as encapsulating "method + environment" rather than just a method. (The state itself is stored in a separate class where necessary.)
Jon Skeet
+1  A: 

You have to declare this on the class level:

private static readonly RegEx badAmpersand = new RegEx("...");
Rinat Abdullin
That should work in this case, but in the general sense it's more complicated than that because there could be concurrency issues in a multi-threaded app. The VB.Net Static member is supposed to be thread-safe.
Joel Coehoorn