There are no stupid questions, only stupid mistakes.
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;
}
}
}
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.