C#中泛型类的算术运算符重载

C#中泛型类的算术运算符重载

给出类似的泛型类定义

public class ConstrainedNumber<T> :
    IEquatable<ConstrainedNumber<T>>,
    IEquatable<T>,
    IComparable<ConstrainedNumber<T>>,
    IComparable<T>,
    IComparable where T:struct, IComparable, IComparable<T>, IEquatable<T>

如何为它定义算术运算符?

以下内容无法编译,因为'+'运算符不能应用于类型'T'和'T':

public static T operator +( ConstrainedNumber<T> x, ConstrainedNumber<T> y){
    return x._value + y._value;}

正如您所见,泛型类型'T'受'where'关键字约束,但我需要对具有算术运算符的数字类型(IArithmetic?)进行约束。

'T'将是一个原始数字类型,如int,float等。这些类型是否存在'where'约束?


富国沪深
浏览 1157回答 3
3回答

尚方宝剑之说

我认为你能做的最好的事情是IConvertible用作约束并做类似的事情:&nbsp;public&nbsp;static&nbsp;operator&nbsp;T&nbsp;+(T&nbsp;x,&nbsp;T&nbsp;y) &nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;T:&nbsp;IConvertible{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;type&nbsp;=&nbsp;typeof(T); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(type&nbsp;==&nbsp;typeof(String)&nbsp;|| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type&nbsp;==&nbsp;typeof(DateTime))&nbsp;throw&nbsp;new&nbsp;ArgumentException(String.Format("The&nbsp;type&nbsp;{0}&nbsp;is&nbsp;not&nbsp;supported",&nbsp;type.FullName),&nbsp;"T"); &nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{&nbsp;return&nbsp;(T)(Object)(x.ToDouble(NumberFormatInfo.CurrentInfo)&nbsp;+&nbsp;y.ToDouble(NumberFormatInfo.CurrentInfo));&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;catch(Exception&nbsp;ex)&nbsp;{&nbsp;throw&nbsp;new&nbsp;ApplicationException("The&nbsp;operation&nbsp;failed.",&nbsp;ex);&nbsp;}}这不会阻止某人传递String或DateTime,所以你可能想要做一些手动检查 - 但IConvertible应该让你足够接近,并允许你进行操作。

桃花长相依

遗憾的是,没有办法将泛型参数约束为整数类型(编辑:我猜“算术类型”可能是一个更好的词,因为这不仅仅与整数有关)。能够做这样的事情会很高兴:where&nbsp;T&nbsp;:&nbsp;integral&nbsp;//&nbsp;or&nbsp;"arithmetical"&nbsp;depending&nbsp;on&nbsp;how&nbsp;pedantic&nbsp;you&nbsp;are要么where&nbsp;T&nbsp;:&nbsp;IArithmetic我建议您通过我们自己的Marc Gravell和Jon Skeet&nbsp;阅读Generic Operators。它解释了为什么这是一个如此困难的问题,以及可以采取哪些措施来解决它。.NET 2.0在.NET世界中引入了泛型,为现有问题的许多优雅解决方案打开了大门。通用约束可用于将类型参数限制为已知接口等,以确保对功能的访问 - 或者对于简单的相等/不等性测试,Comparer.Default和EqualityComparer.Default单例分别实现IComparer和IEqualityComparer(允许我们对元素进行排序)例如,无需了解有关“T”的任何信息。尽管如此,在运营商方面仍存在很大差距。因为运算符被声明为静态方法,所以没有所有数值类型实现的IMath或类似的等效接口;&nbsp;事实上,运营商的灵活性会使这项工作变得非常困难。更糟糕的是:原始类型的许多运算符甚至不作为运算符存在;&nbsp;相反,有直接的IL方法。[强调我的]为了使情况更加复杂,Nullable <>要求“提升运算符”的概念,其中内部“T”描述适用于可空类型的运算符 - 但这是作为语言特征实现的,并且是不是由运行时提供的(使反射更有趣)。
打开App,查看更多内容
随时随地看视频慕课网APP