限制泛型类型参数为数字类型

5

我正在定义一个通用类型:

public class Point<T> where T : IConvertible, IComparable

我真正想要做的是将T限制为数字类型(其中之一为int或float)。在CLR中没有INumeric。是否有可以在此处使用的接口或接口集合,以将类型约束为一个装箱的数字类?


1
这在C#中无法完成。你最多只能创建一个新的IPoint接口来强制执行它。 - parapura rajkumar
可能是[C#:数字的通用接口]的重复问题(https://dev59.com/W0nSa4cB1Zd3GeqPKgog)。 - user7116
4个回答

11
很遗憾,目前还不能实现。这是一个长期以来备受期待的功能
目前最好的选择可能是使用:
where T : struct, IConvertible, IComparable<T>

结构体约束防止使用字符串...

然而,这仍允许使用符合适当约束的任何用户定义的值类型。


IConvertible是最重要的一个接口,它可以在其他接口之上防止非数字类型的使用。除了像Money这样的“单位-度量”结构体之类的用户定义类型外,我想不出还有多少类型会费心去实现这个接口;它很可能是.NET中最大的内置接口契约。 - KeithS
String 实现了 IConvertible 接口,是一种非数值类型。 - phoog
@phoog:这正是我建议添加结构约束的原因——它可以防止使用字符串... - Reed Copsey
抱歉,Reed,那个评论应该是针对@KeithS的。 - phoog

1

where T: struct 会将其限制为值类型。


它仍然可以是任何用户定义的结构,以及内置的非数字结构,如DateTime。 - KeithS

1

一种不太舒适的方式是在构造函数中检查有效类型并抛出异常。它可以工作,但不是“编译器安全”的,并产生运行时错误。 :-(


0

不,你不能这样做。 你可以选择在T:struct,IConvertible,IFormattable,IComparable中限制所有可平铺的数字类型和枚举类型,但即使你进行了限制,你仍然无法在T上使用运算符,因为这些运算符都是静态的。

例如:

point.X-point.Y

由于泛型不知道静态成员,因此会违法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接