I want my object invariant method to throw a specific exception. Does it make sense? Is it possible in C#?
For instance, I have the following code, including class A with invariant method and exception class E. For now class E is not participating in A...
class A {
int x = 0, y = 1;
[ContractInvariantMethod]
private void YisGreaterThanX() {
Contract.Invariant(x < y);
}
}
class E : Exception {
}
And what I need is the following. Like Contract.Requires it would be useful to have Contract.Invariant (or may be an attribute constructor, which accepts Exception-derived class).
class A {
int x = 0, y = 1;
[ContractInvariantMethod]
private void YisGreaterThanX() {
Contract.Invariant<E>(x < y);
}
}
class E : Exception {
}
Is it a good intention? May be my logic is wrong?
Given that we aren't supposed to be catching Contract failures, and since there isn't an overload for Contract.Invariant with an explicit specified exception, this answer is hopefully hypothetical.
So after all the disclaimers, you could hack something along the following lines, by wiring up a ContractFailed event handler:
And in the handler, filter for
Invariant
failures, and handle the failure and re-throw your exception:Given that you can't pass much information in the
Contract.Invariant
definition, if you needed to parameterize the thrown exception, you would need to encode the intended exception into e.g. thebool, string
Contract.Invariant
overload, or use external global state, such as thread local storage.All of these are smelly IMO. So to answer your last question, I believe throwing catchable exceptions isn't a good idea at all - your code is being called out of its designed range of state, so there is a bug / validation missing somewhere.
Edit
Noticed subsequently that handling + throwing in the
ContractFailed
handler is still wrapped in the internalContractException
. So you'll need to unpack, e.g.