Stupid mistakes are often the most painful.
Take the following sample code.
public class Sample{ private int [] array = new int[32]; private int x = 0; public int Foo() { return array[x]; } public int X { get { return this.x; } set { #if DEBUG if (value < 0 || value > 31) return; #endif this.x = value; } }}
public class Sample{ private int [] array = new int[32]; private int x = 0; public int Foo()
{ return array[x];
} public int X { get { return this.x; } set { #if DEBUG if (value < 0 || value > 31) return; #endif this.x = value; } }}
I know that most people who see this probably will probably already know what's wrong with the above, but it's always good to keep in mind. I wrote something like the above and didn't catch it until I came back around to comment what I was doing.
For those who haven't caught it yet, let's assume I'm using a debug build. Therefore, the conditional statement is compiled. Then what if the calling code does something like :
Sample instance = new Sample();instance.X = 33;instance.Foo( );
The first line doesn't modify the class in the Debug build, so Foo just returns array[0] (which is 0). But now assume you use a Release build. instance.x gets changed to 33. The results of the call to instance.Foo( ) now (conveniently) change and will crash with an OutOfRangeException( ).
What I meant to say, should have been something like:
#if DEBUG if (value < 0 || value > 31) throw new ArgumentException("!x");#endif
(where "!x" is a more verbose--and localized--message).
The idea behind checking property assignments in Debug versions is that you have better insight into what exactly is going wrong in order to debug it. Otherwise, Foo( ) might crash with a value of 33, but you won't figure out who assigned that value.