If you can't or don't want to use the static-constructor from the other answers (for example because you have lots of things to do with the type before actually initializing the variables or because you realize that static constructors are a real pain to debug..) you could to other things:
One compile-time solution is to pack the variables in your own type as non-static readonly and hold a static reference to this type
public class Constants { public readonly int MIN; public Constants() { MIN = 18; } } public class Foo { public static Constants GlobalConstants { get; private set; } public static void Main() { // do lots of stuff GlobalConstants = new GlobalConstants(); } }
Or you can make the constant into a property, only providing the getter for anyone outside your class. Note, that the declaring class will still be able to change the property.
public class Foo { public static int MIN { get; private set; } } public static void Main() { MIN = 18; MIN = 23; // this will still work :( } }
Or - if for some strange reason - you really want an exception instead of a compile error, you can make a property out of the constant and throw your exception in the setter.
public class Foo { static int _min; public static int MIN { get { return _min; } set { throw new NotSupportedException(); } } public static void Main() { _min = 18; } }
MIN = 15;line doesn't even compile, so it doesn't throw an exception either.readonlymeans just that. The value can only be set in the constructor, and after that it is constant.