1

Some of my global variables need to be initiated only once. I do it by loading a file and setting them to whatever. Now I want when I try to set a new value to this variable that an exception is thrown.

public class Foo { public static int MIN; private static loadConstants() { MIN = 18; } public static void Main() { loadConstants(); MIN = 15; // this must throw an exception // edit: at least mustn't set the new value } } 

How can I do that ?

(probably very easy and I'm sorry)

4
  • "this must throw an exception" -- Do you really need it to compile, and not fail until runtime? The answers you've got so far ensure the MIN = 15; line doesn't even compile, so it doesn't throw an exception either. Commented Jun 5, 2013 at 13:28
  • TS probably do not mean literally that he wants a row there throwing an exception, just that that line will not set the constant MIN to a value. Commented Jun 5, 2013 at 13:31
  • Yes, exception is not needed. Just the one and only value must persist during runtime. Commented Jun 5, 2013 at 13:34
  • readonly means just that. The value can only be set in the constructor, and after that it is constant. Commented Jun 5, 2013 at 13:37

4 Answers 4

6

Create a static constructor, and mark the variable readonly. Then set the value in the constructor.

public static class Foo { public static readonly int MIN; static Foo() { MIN = 18; } public static void Main() { } } 
Sign up to request clarification or add additional context in comments.

1 Comment

OK I also tried to hack the variable with reflection. And I could set a new value. Can that be avoided somehow without complicating the one-line-declaration of the variable ?
3
public class Foo { public readonly static int MIN; static Foo() { MIN = 18; } public static void Main() { } } 

3 Comments

And this is much better than throwing an exception at runtime if you try to modify it. Doing it this way means the that compiler won't let you modify it other than in the static ctor.
The OP mentioned, he is actually "loading a file" instead of a simple MIN = 18. I strongly recommend to not do any file I/O in static type constructors. Or any complex logic at all. They are a real pain to work with when debugging and its hard to control the exact time when they are executed.
@Imi Yes, I know that and I'm over it. Thank you!
2

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; } } 

Comments

0

Rather than have a public member variable, you could create a public property, and then manage your CONST logic in your implementation.

 private static int? _min; public static int MIN { set { if (!_min.HasValue()) { _min = value; } else { throw; } } get { return _min.ValueOrDefault(); } } 

1 Comment

That will be heavy in my application since I've got around 100 of them.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.