Surprisingly I was only able to find one previous question on SO about this subject, and I\'d just like to get the community \"Vote of Confidence\" (or not!) on my approach.
Often both: Assert, then throw.
You assert because you want to notify developers of a mistaken assumption during development.
You throw because if this happens in a release build, you need to make sure the system doesn't continue processing while in a bad state.
The desired reliability characteristics of your system may affect your choice here, but 'assert then throw' is often a useful strategy, I think.
First, MyClass being valid should be, of course, expressed by MyClass's invariant.
Second, you say "We expect MyMode to be updated by external users of this class" - of course the setter of this mode should have the typical design-by-contract form (as any public function):
void Setter(mode m)
{
// INVARIANT ASSERT (1)
// PRECONDITION ASSERTS (uses "m") (2)
// BODY (3)
// POSTCONDITION ASSERTS (if any) (4)
// INVARIANT ASSERT (5)
}
In (5) you would fail with a screaming assertion violation that the invariant doesn't hold. But in (2) you would fail, earlier, because the mode m passed is invalid. This would send a clear message to the user and thus solves your problem.
And please don't tell me that the mode field is public and users change it without any control whatsoever.
Edit: About assertions and release mode, see also:
Are assertions always bad?
When should assertions stay in production code?
Design by contract using assertions or exceptions?