在 C# 中是否可以将函数泛型限制为数字?例如,我想创建一个 Bounds 结构来保存某物的最小和最大边界。限制只能是数字,但可以是 and int, and float, and double, 等等。
我有想法通过结构泛型来实现这一点,并将该泛型限制为仅给定的类型,如下所示:
struct Bounds<T> where T: int, float, double {
T Min, Max;
// Далее можно будет, например реализовать метод проверки числа в границах:
bool isInBounds (T num)
=> num >= Min && num <= Max;
}
但是,这样的实现会引发错误:"int" не является допустимым ограничением.
似乎结构泛化根本不能成为约束!
如果没有,怎么可能引入这样的限制?
如果是这样,除了做这样的事情之外,是否有更漂亮的方法来引入类似的约束:
public struct Bounds <T> {
T Min, Max;
public Bounds<T> (T min, T max) {
if (typeof(T) == typeof(int) || typeof(T) == typeof(float) || ...) {
Min = min;
...
}
else
throw new Exception(...);
}
}
这取决于您要支持哪种操作。
目前,还没有完全支持这样的接口
INumeric,因为没有什么东西可以填充这个接口:在 C# 中,还没有对这样的运算符+或<接口中的运算符的支持。然而,这方面的工作正在进行中,随着语言的发展,这样的机会将会出现。这里[1]、[2]的工作正朝着这个方向进行,到目前为止,还只是在设计和理解它的外观方面。当出现这样的接口时
INumeric,可以将其作为通用约束,同时进行加法、比较等操作。您原则上可以将运行时检查移动到静态构造函数中:
那么每次实例化都不会花费时间
Bounds<T>。如果您只需要一些功能并且并不真正关心漂亮的语法,您可能会考虑手动实现它,但效率可能会受到影响。这里有些例子:
根据名称
Bounds,正如评论中正确建议的那样,只有一个可能对您来说就足够了IComparable<T>。在这种情况下,限制为数字类型没有多大意义,你可以写如果您需要更高级的操作,您可以使用前面提到的答案中的代码,或者从 Genumerics nuget包中获取现成的实现: