In writing some code to mimic an as-complete-as-possible emulation of System.Array, I have come across something that I find confusing and dangerous.
With the following method signature:
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static int BinarySearch<T>(T[] array, T value, IComparer<T> comparer)
A method is declared with a contract saying that it will definitely not corrupt any state, even itself, if there is a failure. It also implies that some code external to the contract will be called via the comparer
value, and IComparer<T>.Compare
does not require a reliability contract; a call to comparer.Compare(x,y)
can certainly corrupt state and violate the contract.
How is this valid? I'm not an expert on the uses of constrained execution... will a constrained execution environment inspect the Compare
method at runtime, and cause an exception if the contract is expected to be enforced? Is this a hole in the reliability contract?
Or, are constrained execution regions CIL voodoo that I should avoid in non-framework code? I want to keep as close as possible behavior to native System.Array, and so I would like to maintain the same ReliabilityContract
attributes where the underlying implementation supports it; but it seems to me that even the internals can't guarantee the contract, so I am quite puzzled how I could guarantee the contract.