Thursday, January 31, 2008

JP Boodhoo, You Magnificent Bastard!

For a little while now, my co-workers and I have been watching videos from dnrTV over lunch once a week. Recently we have been watching JP Boodhoo's series on demystifying design patterns, which has been nothing short of excellent. But one of the neatest things I learned while watching was something he and the host mostly glossed over: A strongly typed Constants class.

In the past when I've done a Constants class, it has looked something like this:

22 public class MyConstants

23 {

24 public const string MyFirstValue = "VALUE1";

25 public const string MySecondValue = "VALUE2";

26 }


Then to use them it goes sort of like this:

17 public class MyClass

18 {

19 public string MyValue { get; set; }

20 }


8 class Program

9 {

10 static void Main(string[] args)

11 {

12 MyClass myObj = new MyClass { MyValue = MyConstants.MyFirstValue };

13 Console.Write(myObj.MyValue);

14 }

15 }


Which would print out "VALUE1".

This works out fine, but has an inherent flaw: you are still just passing around a string, and there is nothing stopping someone from forgetting there is a class of constants and simply assigning their own random string value. This is where JP comes in. In this episode, somewhere near the end, he whips up a quick strongly-typed Constants class, and it works really, really well. Here's what my example above would look like if I had a quarter of Mr. Boodhoo's intelligence:

22 public class MyConstants

23 {

24 public static readonly MyConstants MyFirstValue = new MyConstants();

25 public static readonly MyConstants MySecondValue = new MyConstants();

26

27 private MyConstants() { }

28 }


Now when you use it, it can be typed:

17 public class MyClass

18 {

19 public MyConstants MyValue { get; set; }

20 }


8 class Program

9 {

10 static void Main(string[] args)

11 {

12 MyClass myObj = new MyClass { MyValue = MyConstants.MyFirstValue };

13 Console.Write(myObj.MyValue);

14 }

15 }


Which would print out... ConsoleApplication1.MyConstants? Oh crap, we're only part way there. But JP didn't leave us much to do, we just need to find a way to get a string value out of that object. Here's what our class could look like now:

22 public class MyConstants

23 {

24 public static readonly MyConstants MyFirstValue =

25 new MyConstants("VALUE1");

26 public static readonly MyConstants MySecondValue =

27 new MyConstants("VALUE2");

28 private readonly string value;

29

30 private MyConstants(string value)

31 {

32 this.value = value;

33 }

34

35 public override string ToString()

36 {

37 return value;

38 }

39 }


Now let's use it again:

17 public class MyClass

18 {

19 public MyConstants MyValue { get; set; }

20 }


8 class Program

9 {

10 static void Main(string[] args)

11 {

12 MyClass myObj = new MyClass { MyValue = MyConstants.MyFirstValue };

13 Console.Write(myObj.MyValue.ToString());

14 }

15 }


Pretty sweet eh?

1 comment:

Kamran A said...

Cool. This is great for when an Enum just doesn't cut it (string constant values, no "default" allowed).