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.