我有以下方法:
public static bool IsBetween<T>(this IComparable<T> value, T lowerBound, T upperBound)
where T : IComparable<T>
{
Contract.Requires<>(value != null);
Contract.Requires<>(lowerBound != null);
Contract.Requires<>(upperBound != null);
Contract.Requires<>(upperBound.CompareTo(lowerBound) >= 0);
return IsBetween(value, lowerBound, upperBound, InclusionOptions.None);
}
public static bool IsBetween<T>(this IComparable<T> value, T lowerBound, T upperBound,
InclusionOptions options) where T : IComparable<T>
{
Contract.Requires<>(value != null);
Contract.Requires<>(lowerBound != null);
Contract.Requires<>(upperBound != null);
Contract.Requires<>(upperBound.CompareTo(lowerBound) >= 0); //Code Contracts Issue
...
}
这里的问题是它不喜欢我的上一个要求。它声明CodeContracts: requires unproven: upperBound.CompareTo(lowerBound) >= 0
。我不太确定在这里解决这个问题的正确方法。我需要确保当我执行比较值时,我实际上有一个真正的lowerBound和upperBound值,并且lowerBound值不高于upperBound值。
哦,我不能使用实际的&lt;或者&gt;运算符,因为您无法将它们应用于“T”类型。
最后,我知道可以是一个单独的问题,但它是高度相关的......如果有人知道为什么我在使用Code Contracts v1.4.50126时仍然会收到CA1062代码分析错误。 1请告诉我如何解决问题:CA1062: Microsoft.Design : In externally visible method 'MyClass.IsBetween<T>(this IComparable<T>, T, T), validate parameter 'upperBound' before using it.
答案 0 :(得分:0)
您的方法的问题在于,当您调用upperBound.CompareTo
时,您假设编译器知道类型T
(这是upperBound
参数的声明类型)实现IComparable<T>
接口(声明CompareTo
方法)。
通常情况(按照惯例)IComparable<T>
接口将由类型T
实现(如果有的话);但是,除非您通过类型约束明确指定它,否则编译器不会知道它。
public static bool IsBetween<T>(this T value, T lowerBound, T upperBound)
where T : IComparable<T>
{
Contract.Requires(value != null);
Contract.Requires(lowerBound != null);
Contract.Requires(upperBound != null);
Contract.Requires(upperBound.CompareTo(lowerBound) >= 0);
// ...
}
答案 1 :(得分:0)
我将以int
为例。
int.CompareTo(int)
的合同无法确保任何特定的返回值。 你知道如果a >= b
,那么a.CompareTo(b) >= 0
,但由于这没有被表达为合同,静态检查员唯一看到的是“a.CompareTo(b)返回一个int“。 “一个int”不能被证明是非负的。
您应该可以添加类似
的内容Contract.Assert(a >= b);
Contract.Assume(a.CompareTo(b) >= 0);
在你称之为功能的地方。这使静态检查器首先尝试证明a >= b
并通知您是否无法证明这一点,然后相信您已满足功能要求。
如果您经常为int
调用此函数,则可能需要使用此修改后的int
特定合同创建包装函数:
public static bool IsBetween(this int value, int lowerBound, int upperBound)
{
Contract.Requires<>(value != null);
Contract.Requires<>(lowerBound != null);
Contract.Requires<>(upperBound != null);
Contract.Requires<>(upperBound >= lowerBound);
Contract.Assume(upperBound.CompareTo(lowerBound) >= 0);
return IsBetween<int>(value, lowerBound, upperBound);
}
和其他类型相似。