通用约束匹配数字types

我想写一个扩展方法的数字types,用于我正在build设的stream利的testing框架。 基本上我想这样做:

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

where T : struct不行的地方,因为那也会匹配stringbool ,还有可能是别的我忘记了。 有什么我可以做只匹配数字types? (特别是实现><运算符的types,所以我可以比较它们…如果这意味着我也匹配date,这并不重要 – 扩展仍然会做我期望的。)

在这种情况下,你想限制你的generics为IComparable接口,这使得你可以访问CompareTo方法,因为这个接口允许你回答问题ShouldBeGreaterThan

数字types将实现该接口,它也适用于string的事实不应该打扰你。

 where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable 

这是最接近我可以得到一个数字约束。 所有的数字types都实现了这5个接口,但是IFormattable不是由bool实现的,string是引用types,所以不适用。

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

 public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T> { return actual.CompareTo(comp) > 0; } 

你也可以添加结构约束。

由于没有像INumeric这样常见的filter,所以很难将其限制在数字上。 实际上,我怀疑这里最简单的方法是不要坚持约束,并在方法内部使用Comparer<T>.Default.Compare

这种内置types既支持genericsIComparable<T> ,也支持非genericsIComparable ,并且通过Nullable<T>支持引用types,值types和提升用法。

对于完整的操作符用法,请查看MiscUtil的Operator类和GreaterThan等,如果您真的想使用操作符(而不是接口),这可能会很有用。 它还提供了访问像Add等其他运营商

Stackoverflow充满了这种问题。 看看这个search 。 C#不支持定义受数字约束的genericstypes。 不幸的是,最好的办法是在所有对象上实现扩展方法,并根据types进行切换,或为int,double,float等创build一组方法。

此解决方法可能有所帮助: 使用策略的解决方法 。 它提供了编译时的安全性。