88

我正在尝试为数字类型编写一个扩展方法,以在我正在构建的流畅测试框架中使用。基本上,我想这样做:

public static ShouldBeGreaterThan<T>(this T actual, T expected, string message)
    where T : int || T: double || etc...

只是where T : struct不这样做,因为那也将匹配stringand bool,并且可能还有其他我忘记的东西。我能做些什么来只匹配数字类型吗?(具体是实现>and<运算符的类型,所以我可以比较它们......如果这意味着我也在匹配日期,那并不重要 - 扩展仍然会按照我的预期进行。)

4

6 回答 6

63

在这种情况下,您希望将泛型约束到IComparable接口,这使您可以访问该CompareTo方法,因为该接口允许您回答问题ShouldBeGreaterThan

数字类型将实现该接口,并且它也适用于字符串这一事实不应该让您感到困扰。

于 2010-07-25T14:48:52.567 回答
54
where T : struct, 
          IComparable, 
          IComparable<T>, 
          IConvertible, 
          IEquatable<T>, 
          IFormattable

这是我能得到的最接近数字约束的值。所有数值类型都实现了这5个接口,但IFormattable不是bool实现的,字符串是引用类型,所以不适用。

还有一些其他的东西可以实现这些 - 例如 DateTime ,所以它并不是真正需要的,但可以防止很多你不想要的实例化。

于 2010-07-25T15:21:43.537 回答
20
public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T>
{
    return actual.CompareTo(comp) > 0;
}

如果需要,您也可以添加结构约束。

于 2010-07-25T14:55:37.230 回答
9

很难仅限于数字,因为没有什么常见INumeric的过滤器可以用作过滤器。实际上,我怀疑这里最简单的方法是坚持约束,而是Comparer<T>.Default.Compare在方法内部使用。

这种内置类型同时支持泛型IComparable<T>和非泛型IComparable,并支持 ref-types、value-types 和提升使用 via Nullable<T>

对于完整的运算符用法,请查看MiscUtil 的Operator等,如果您真的想使用运算符(而不是接口)GreaterThan,这可能很有用。它还提供对其他运算符的访问,例如etc。Add

于 2010-07-25T15:10:09.477 回答
5

Stackoverflow 充斥着这样的问题。 看看这个搜索。C# 不支持定义受数字约束的泛型类型的方法。遗憾的是,最好的办法是在所有对象上实现扩展方法,并根据类型进行切换,或者为整数、双精度、浮点数等创建一组方法。

于 2010-07-25T14:44:38.933 回答
0

This workaround may help: Workaround using policies. It provides compile time safety.

于 2011-02-07T12:44:37.950 回答