[.net] Why no globals? Arg!

Started by
10 comments, last by Sneftel 17 years, 8 months ago
Why is it that I feel so constrained by the fact that everything in C# centers around classes, and that as such one can't have global variables? Is it because I'm too used to procedural programming? Should one ideally even have to pass "global" variables through class constructors from one class to another, which I seem to be doing alot, in C#? Or is having to do that a result of bad design?
_______________________Afr0Games
Advertisement
It have to do with either bad design or non-OO design. C# is exclusivly for OOP (other paradigms can be used, but not easily). In OOP there is no such thing as a global variable everything is an object, and every object is a member of a function or another object. What kind of stuff do you consider for globals?
Well you could use static classes.
public sealed class Globals{     public static int SomeStupidInteger = 0;}


There now every class can access Globals.SomeStupidInteger.

However I'm pretty sure this is frowned upon in C#. If you want something that other classes can access, I believe creating a singleton is considered the "better" method.
Classes really should strive to be as re-entrant as reasonable.
For the (extremely rare) case where a global variable is the best option, and you have compelling reasons that static classes with static methods are worse options, you can create objects in the global namespace by emiting MSIL code, linking with something containing it, and other methods. But I wouldn't do it. I have seen it exactly once in the years I have been programming with C#, and that was because of difficult circumstances while also working with badly written managed C++.

Global variables have a whole lot of badness. Sure they made sense in C and languages developed without the concept of encapsulation, but there is no reason to use them in day-to-day code any more. yay!
Quote:Original post by CTar
What kind of stuff do you consider for globals?


Here's a very recent example:

        //Note: This must be passed through to the account creation window and        //      subsequently to the main game window through the respective        //      constructors, as this will always be used as the main connection        //      to all servers.        private NetFXSocket Socket;        StateObject UserState;


Now, some might argue that I could change the socket variable in the StateObject class to be of type NetFXSocket instead, but as it turns out, it has proven easier to work with native Socket objects on the server side (this code is from a client), and partially on the client side. Main reason being that NetFXSocket(s) were never designed to be used for much more than simplifying the process of setting up a socket for internet usage, client wise and server wise. True, the NetFXSocket class does have a public reference to it's internal Socket object, but if I started using that with StateObject, I'd have to use three levels of indirection everytime I wanted to access my socket, and that's just bothersome.

Edit: That last statement is especially true in regards to having to break up statements and function calls and whatnot (to avoid them going outside of the screen), something I hate doing because I think it makes the code look ugly.
_______________________Afr0Games
Quote:Original post by Scet
However I'm pretty sure this is frowned upon in C#. If you want something that other classes can access, I believe creating a singleton is considered the "better" method.
The battle between the singleton pattern vs the static class solution is a never ending battle and really comes down to personal preference.

I personally prefer the static class as I find Globals.SomeStupidInteger prettier then Globals.Instance.SomeStupidInteger. You can also have complete control over what happens during initialization:

public sealed class Globals{     static Globals()     {          SomeStupidString = "Yo, Hommy!";     }     public static string SomeStupidString;     public static int SomeStupidInteger = 0;}


The static constructor will be called the first time the static class Globals is used.
Rob Loach [Website] [Projects] [Contact]
Does C# [or, I suppose, .Net in general] suffer from the pitfalls that make singletons in C++ neccessary to begin with? I've never really looked into it, but it seems like the details of static objects would have been fleshed out better in the specifications.

CM

Personally I find it very rare you need a global static, and if you do, make it a global property with only a getter.
Ie, don't let some random code set it to null. This could play havok with the rest of your program.

constants are good too.

public const int SomeStupidInteger = 0;



Generally, I do not use publically visible static objects in my current project.
That said, I do have 'singletons', which are tied to the current instance of the application (using thread statics to reference the application instance) but this sort of thing is quite tricky and you can get memory leaks if you are not careful.

At work is a tad different. We are using axiom, and that thing is filled to the brim with statics. Honestly it's actually been damned annoying. First thing it means is we can't have two copies of the engine running independantly, and there isn't any explicit 'shutdown' which kills all the statics.. Required quite a bit of hack and slash to get it running twice in a row without leaking buckets of memory.


As for the original example, connection sockets. I see no reason why you want to limit yourself to one connection. You never know what may be required in the future. The moment you need 2 connections, you are screwed.
Quote:Original post by Afr0m@n
Should one ideally even have to pass "global" variables through class constructors from one class to another, which I seem to be doing alot, in C#?

Ideally, yes. They shouldn't be global, they should just be passed to the classes that need them.

This topic is closed to new replies.

Advertisement