Search code examples
c#javaexceptioncode-contracts

Contract statements and assertions


This is the code from custom Microsoft .NET runtime implementation and I have the following questions:

    public static string ToBase64String(byte[] inArray, int offset, int length)
    {
        if (inArray == null) throw new ArgumentNullException("inArray");
        if (offset < 0) throw new ArgumentOutOfRangeException("offset");
        if (length < 0) throw new ArgumentOutOfRangeException("length");
        if (offset + length > inArray.Length)
            throw new ArgumentException("offset + length > inArray.Length");

        // Fast return for the zero length case, note that this scenario is
        // absolutely valid.
        if (length == 0) return "";
        // ....
    }

Shouldn't the statements, which check the prerequisities (code contract) for this method actually be assert-like? I mean, where did the ideology of throwing exceptions for code contract violations come from?

I could easily understand the following code:

Contract.Requires(inArray != null);
Contract.Requires(offset >= 0);
// ...

But throwing different exceptions... Why?

It's impossible to handle this sort of exception correctly, because it merely indicates the logic flaw, this error is similiar to unchecked exception in Java, when you also shouldn't even attempt to handle it.

Now - am I right? Maybe I don't understand some underlying principles or tend to over-engineer everything?


Solution

  • Even with Code Contracts, it's a best practice to throw specific exceptions in release code, like this:

    Contract.Requires<ArgumentNullException>(...);
    

    First: In your release/production code, you don't want to show assert windows to the user.

    The alternative to that is throwing a ContractException, but this exception cannot be 'catched' because it is declared internal.

    The only alternative left to allow the caller of your code to handle some exceptions gracefully ( eg: like invalid input from a user) is to throw exceptions he can catch.

    The big advantage to Code Contracts is that the caller can actually see the exceptions you will be throwing ( via sandcastle auto-documentation, the *.Contracts.dlls, plugins & tools, ... ) and guard himself against these exceptions. Without Code Contracts, he'd have to rely on a (probably dated) XML documentation or even nothing at all.