views:

712

answers:

6

I'm currently doing a project in C# with a lot of rendering, and throughout almost all the classes there's a constant value of the type integer being used for scaling of the rendering. I know I could define this constant in one place as a normal variable and then pass it around, but this seemes really cumbersome. When is it acceptable to use static variables in C#? The easiest solution to my problem would be to create a class containing the static variable that all the other classes could reference - would that be bad design?

+5  A: 

No, that would actually be a perfect candidate for static variables. You can even go one step further and make the class static, so that it can't be instantiated. You can then add all your constants to that class as well as some helper methods if necessary.

BFree
+3  A: 

Not bad design at all. In fact, having a Common or Utility namespace and class that exposes static methods and static values centralizes these values in one place so you can ensure that every module in you application is using the appropriate values. It's low cohesion, but acceptable for the benefit. I see no problem with it.

JP Alioto
+2  A: 

The answer is that if the program works and is maintainable, do it.

Static variables aren't a sin, it is just good to know when to use them. :)

Craig
+5  A: 

How constant is the value? static is fine for things that are readonly, but you can quickly get into a mess if it isn't readonly - especially if you have multiple threads. The scaling factor doesn't sound like a hard constant to me - i.e. it isn't:

public const double ScaleFactor = 1;

I wouldn't hesitate to use a static variable for something I load once and leave alone. Other than that, I'd probably encapsulate (in your case) some kind of RenderContext with this value and any other utility methods - and pass the RenderContext between methods; this can also help you abstract away from the underlying implementation if you need to unit test, etc.

As you find you need more properties (and you inevitably will), you just extend the RenderContext class - nothing else changes.


(edit)

Also - consider the future: will you ever be doing more than one render at once? Since we all have lots of cores now, etc... static is good if all the threads share a value. There is [ThreadStatic], but that is a bit messy by comparison.

Marc Gravell
+1  A: 

If all your classes have to understand this value + do something else, then (unless it's something like pi) you probably should check that your classes have a single concern. Perhaps that 'value' needs to become an object that can do the operations that are currently being done all over your codebase?

Alun Harford
+1  A: 

I wanted to add something to the other answers.

In games, what you're doing is fairly common. So just look at the other answers. But to add on to your current situation:

If these are game constants, like player health, gravity, speed of entities, etc...I would not hardcode them.

Rather, make these global, but load them from a file. This way you can tweak your game without requiring a rebuild of everything that uses these globals, which will be a lot of things.

GMan
In that case, you can just create an environment object and use your IOC container to pass that where it's needed
Alun Harford