3 回答
TA贡献1788条经验 获得超4个赞
我认为你能做的最好的事情是IConvertible
用作约束并做类似的事情:
public static operator T +(T x, T y) where T: IConvertible{ var type = typeof(T); if (type == typeof(String) || type == typeof(DateTime)) throw new ArgumentException(String.Format("The type {0} is not supported", type.FullName), "T"); try { return (T)(Object)(x.ToDouble(NumberFormatInfo.CurrentInfo) + y.ToDouble(NumberFormatInfo.CurrentInfo)); } catch(Exception ex) { throw new ApplicationException("The operation failed.", ex); }}
这不会阻止某人传递String或DateTime,所以你可能想要做一些手动检查 - 但IConvertible应该让你足够接近,并允许你进行操作。
TA贡献1860条经验 获得超8个赞
遗憾的是,没有办法将泛型参数约束为整数类型(编辑:我猜“算术类型”可能是一个更好的词,因为这不仅仅与整数有关)。
能够做这样的事情会很高兴:
where T : integral // or "arithmetical" depending on how pedantic you are
要么
where T : IArithmetic
我建议您通过我们自己的Marc Gravell和Jon Skeet 阅读Generic Operators。它解释了为什么这是一个如此困难的问题,以及可以采取哪些措施来解决它。
.NET 2.0在.NET世界中引入了泛型,为现有问题的许多优雅解决方案打开了大门。通用约束可用于将类型参数限制为已知接口等,以确保对功能的访问 - 或者对于简单的相等/不等性测试,Comparer.Default和EqualityComparer.Default单例分别实现IComparer和IEqualityComparer(允许我们对元素进行排序)例如,无需了解有关“T”的任何信息。
尽管如此,在运营商方面仍存在很大差距。因为运算符被声明为静态方法,所以没有所有数值类型实现的IMath或类似的等效接口; 事实上,运营商的灵活性会使这项工作变得非常困难。更糟糕的是:原始类型的许多运算符甚至不作为运算符存在; 相反,有直接的IL方法。[强调我的]为了使情况更加复杂,Nullable <>要求“提升运算符”的概念,其中内部“T”描述适用于可空类型的运算符 - 但这是作为语言特征实现的,并且是不是由运行时提供的(使反射更有趣)。
- 3 回答
- 0 关注
- 1156 浏览
添加回答
举报