У меня очень простой класс, использующий контракты .NET Code:
public class ContractSquareRoot
{
/// <summary>
/// Makes your life much easier by calling Math.Sqrt for you. Ain't that peachy.
/// </summary>
/// <param name="value">The value to calculate the square root from. No negatives!</param>
/// <returns>The square root of the given value. Obviously always > 0.</returns>
public double CalculateSquareRoot(double value)
{
Contract.Requires<ArgumentException>(0 <= value);
Contract.Ensures(0 <= Contract.Result<double>());
double squareRoot = Math.Sqrt(value);
return squareRoot;
}
}
Когда я вызываю метод с отрицательным значением, я ожидаю, что статический анализ кода предупредит меня об этом.
class Program
{
static void Main(string[] args)
{
var barMansSquareroot = new ContractSquareRoot();
// This should not be possible...
barMansSquareroot.CalculateSquareRoot(-42);
}
}
Но даже если Contract.Requires
не выбрасывает желаемое исключение, анализ статического кода отмечает каждое утверждение как правильное. Интересно, что он предупреждает меня о нарушении, когда я меняю тип значения на int
или заменяю <=
на <
. Недопустимое поведение ограничено double
и float
. Я предполагаю, что это имеет какое-то отношение к точности значений с плавающей запятой.
Это даже работает, когда я формулирую требование следующим образом:
Contract.Requires<ArgumentException>(!(0 > value));
Является ли это ошибкой или я делаю что-то неправильно?