比较运算符的重载

2. 比较运算符的重载

C#中有6个比较运算符,它们分为3对:

       == 和 !=

       > 和 <

       >= 和 <=

C#要求成对重载比较运算符。如果重载了==,也必须重载!=,否则会产生编译错误。另外,比较运算符必须返回bool类型的值。这是它们与算术运算符的根本区别。两个数相加或相减的结果,理论上取决于数的类型。而两个Vector的相乘会得到一个标量。另一个例子是.NET基类System.DateTime,两个DateTime实例相减,得到的结果不是DateTime,而是一个System.TimeSpan实例,但比较运算得到的如果不是bool类型的值,就没有任何意义。

注意:

在重载==和!=时,还应重载从System.Object中继承的Equals()和GetHashCode()方法,否则会产生一个编译警告。原因是Equals()方法应执行与==运算符相同的相等逻辑。

除了这些区别外,重载比较运算符所遵循的规则与算术运算符相同。但比较两个数并不像想象的那么简单,例如,如果比较两个对象引用,就是比较存储对象的内存地址。比较运算符很少进行这样的比较,所以必须编写运算符,比较对象的值,返回相应的布尔结果。下面给Vector结构重载==和!=运算符。首先是==的执行代码:

      public static bool operator = = (Vector lhs, Vector rhs)

      {

         if (lhs.x = = rhs.x && lhs.y = = rhs.y && lhs.z = = rhs.z)

            return true;

         else

            return false;

      }

这种方式仅根据矢量组成部分的值,来对它们进行等于比较。对于大多数结构,这就是我们希望的,但在某些情况下,可能需要仔细考虑等于的含义,例如,如果有嵌入的类,是应比较对同一个对象的引用(浅度比较),还是应比较对象的值是否相等(深度比较)?

注意:

不要通过调用从System.Object中继承的Equals()方法的实例版本,来重载比较运算符,如果这么做,在objA是null时计算(objA==objB),这会产生一个异常,因为.NET运行库会试图计算null.Equals(objB)。采用其他方法(重写Equals()方法,调用比较运算符)比较安全。

还需要重载运算符!=,采用的方式如下:

      public static bool operator != (Vector lhs, Vector rhs)

      {

      return ! (lhs == rhs);

      }

像往常一样,用一些测试代码检查重写方法的工作情况,这次定义3Vector对象,并进行比较:

      static void Main()

      {

         Vector vect1, vect2, vect3;

         vect1 = new Vector(3.0, 3.0,–10.0);

         vect2 = new Vector(3.0, 3.0,–10.0);

         vect3 = new Vector(2.0, 3.0, 6.0);

         Console.WriteLine("vect1= =vect2 returns " + (vect1= =vect2));

         Console.WriteLine("vect1= =vect3 returns " + (vect1= =vect3));

         Console.WriteLine("vect2= =vect3 returns " + (vect2= =vect3));

         Console.WriteLine();

         Console.WriteLine("vect1!=vect2 returns " + (vect1!=vect2));

         Console.WriteLine("vect1!=vect3 returns " + (vect1!=vect3));

         Console.WriteLine("vect2!=vect3 returns " + (vect2!=vect3));

      }

编译这些代码(下载代码中的Vectors3.cs),会得到一个编译器警告,因为我们没有为Vector重写Equals(),对于本例,这是不重要的,所以忽略它。

csc Vectors3.cs

Microsoft (R) Visual C# 2005 Compiler version 8.00.50215.33

for Microsoft (R) Windows (R) Framework version 2.0.50215

Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

 

Vectors3.cs(5,11): warning CS0660: 'Wrox.ProCSharp.OOCSharp.Vector' defines

       operator = = or operator != but does not override Object.Equals(object o)

Vectors3.cs(5,11): warning CS0661: 'Wrox.ProCSharp.OOCSharp.Vector' defines

        operator = = or operator != but does not override Object.GetHashCode()

在命令行上运行该示例,生成如下结果:

Vectors3

vect1= =vect2 returns True

vect1= =vect3 returns False

vect2= =vect3 returns False

 

vect1!=vect2   returns False

vect1!=vect3    returns True

vect2!=vect3    returns True

3. 可以重载的运算符

并不是所有的运算符都可以重载。可以重载的运算符如表5-5所示。

表 5-5

类    别

运 算 符

限    制

算术二元运算符

+, *, /, –, %

算术一元运算符

+, –, ++, ––

按位二元运算符

&, |, ^, <<, >>

按位一元运算符

!, ~, true, false

true和false运算符必须成对重载

比较运算符

==, !=, >=, <, <=, >

必须成对重载

赋值运算符

+=,–=,*=,/=,>>=,<<=,%=

,&=,|=,^=

不能显式重载这些运算符,在重写单个运算符如+,–,%等时,它们会被隐式重写

索引运算符

[]

不能直接重载索引运算符。第2章介绍的索引器成员类型允许在类和结构上支持索引运算符

数据类型转换运算符

()

不能直接重载数据类型转换运算符。用户定义的数据类型转换(本章的后面介绍)允许定义定制的数据类型转换


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值