Considérons les deux morceaux de code suivants :
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);
}
et
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);
}
Je préfère personnellement la première version car le code est beaucoup plus clair et plus petit, et les Contrats peuvent être facilement désactivés. Mais l'inconvénient est que Visual Studio Code Analysis me reproche de vérifier que la valeur du paramètre n'est pas nulle et que les Contrats du constructeur ne réalisent pas que le regex garantit que la minute et l'heure sont comprises dans les limites données.
Je me retrouve donc avec un grand nombre d'avertissements erronés et je ne vois aucun moyen de valider des valeurs de chaîne avec des contrats sans finir par lancer des FormatExceptions, à part une validation RegEx.
Avez-vous des suggestions sur la manière de résoudre cette situation et d'autres situations équivalentes en utilisant les contrats de code ?