views:

895

answers:

1

Hi, consider the following two pieces of code:

    public static Time Parse(string value)
    {
        string regXExpres = 
           "^([0-9]|[0-1][0-9]|2[0-3]):([0-9]|[0-5][0-9])$|^24:(0|00)$";
        Contract.Requires(value != null);
        Contract.Requires(new Regex(regXExpres).IsMatch(value));
        string[] tokens = value.Split(':');
        int hour = Convert.ToInt32(tokens[0], CultureInfo.InvariantCulture);
        int minute = Convert.ToInt32(tokens[1], CultureInfo.InvariantCulture);
        return new Time(hour, minute);
    }

and

    public static Time Parse(string value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }
        string[] tokens = value.Split(':');
        if (tokens.Length != 2)
        {
            throw new FormatException("value must be h:m");
        }
        int hour = Convert.ToInt32(tokens[0], CultureInfo.InvariantCulture);
        if (!(0 <= hour && hour <= 24))
        {
            throw new FormatException("hour must be between 0 and 24");
        }
        int minute = Convert.ToInt32(tokens[1], CultureInfo.InvariantCulture);
        if (!(0 <= minute && minute <= 59))
        {
            throw new FormatException("minute must be between 0 and 59");
        }
        return new Time(hour, minute);
    }

I personally prefer the first version because the code is much clearer and smaller, and the Contracts can be easily turned off. But the disadvantage is that Visual Studio Code Analysis blames that I should check the parameter value for null and the Contracts of the constructor do not realize that the regex ensures that minute and hour are within the given boundarys.

So i end up having a lot of wrong warnings and I see no way to validate string values with contracts without ending up throwing FormatExceptions other than a RegEx validation.

Any suggestions how you would solve this and equivalent situations using Code contracts?

+6  A: 

In order to get rid of warnings you can use Contract.Assume

Dzmitry Huba
this sort of solves my problem.If I add the following lines in front of the return statement all the wrong warnings are gone.The only thing I still do not really like is that these lines are somehow blowing up the code. But I guess it's impossible for code contracts to get the meaning of regular expressions. Contract.Assume(0 <= hour Contract.Assume(0 <= minute
steveee
@steveee, you should always split contracts on conjunctions, so that `Contract.Assume(0 <= hour ` becomes `Contract.Assume(0 <= hour); Contract.Assume(hour <=24);`
Porges