分享

09 C# 第九章 引用类型

 雪柳花明 2016-10-27

重写Object成员

重写 ToString()

代码实例:

[csharp] view plain copy
  1. namespace _01ObjectOverloading  
  2. {  
  3.     class Program  
  4.     {  
  5.         class Coordinate  
  6.         {  
  7.             private int m_nX;  
  8.             private int m_nY;  
  9.   
  10.             public Coordinate(int x, int y)  
  11.             {  
  12.                 m_nX = x;  
  13.                 m_nY = y;  
  14.             }  
  15.   
  16.             public override string ToString()  
  17.             {  
  18.                 return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);  
  19.             }  
  20.         }  
  21.   
  22.         static void Main(string[] args)  
  23.         {  
  24.             Coordinate testToStingOverride = new Coordinate(10, 20);  
  25.   
  26.             Console.WriteLine(testToStingOverride);  
  27.   
  28.             Console.ReadKey();  
  29.         }  
  30.     }  
  31. }  


测试结果:
Coordinate:  x= 10, y=20



重写 GetHashCode() 和 Equals()

GetHashCode() 和 Equals() 是object 可以重写的另两个方法,而且重写 Equals() 时系统要求重写
GetHashCode(),否则编译时会出现告警。原因是当我们想判断两个对象是否相等时,对于HashCode的
检查也是其中的一项,所以重写了 Equals(),系统也会提示重写 GetHashCode()。


重写 GetHashCode()主要是其中的Hash算法,算法的性能,安全等等,这里不介绍Hash算法了,太多了。
重写 Equals()时,要主意两个概念,对象的同一性和相等的对象值。
对象的同一性:是指两个对象的引用指向的是堆上同一块内存地址,我们可以用 API ReferenceEquals() 来检查
两个对象是不是同一的。可以看作是物理上的。
对象的相等性:是指我们可以认为对象的某些成员变量的值相等了,这两个对象就相等了。例如我们可以为
同一个人创建两个对象,这两个对象中身份证号码是一样的,我们就可以认为这两个对象是描述的同一个人的
他们是相等的。
    重写 Equals() 方法的一些关键点:(这个比较有用,实际情况下可以照搬一下,提高代码可靠性)
1) 检查是否为空
2) 如果是引用类型,就检查引用是否相等
3) 检查数据类型是否相等
4) 调用了一个指定了具体类型的辅助方法,
5) 检查散列码是否相等
6) 如果基类重写了Equals(),就检查 base.Equals()
7) 比较每一个标识字段,判断是否相等
8) 重写GetHashCode()
9) 重写 == 和 != 运算符


代码实例:(包括了重写 GetHashCode() 和 Equals())

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace _01ObjectOverloading  
  6. {  
  7.     class Program  
  8.     {  
  9.         class Coordinate  
  10.         {  
  11.             private int m_nX;  
  12.             private int m_nY;  
  13.   
  14.             public Coordinate(int x, int y)  
  15.             {  
  16.                 m_nX = x;  
  17.                 m_nY = y;  
  18.             }  
  19.   
  20.             public int X  
  21.             {   
  22.                 get {return m_nX;}  
  23.             }  
  24.             public int Y  
  25.             {  
  26.                 get { return m_nY; }  
  27.             }  
  28.   
  29.             public override string ToString()  
  30.             {  
  31.                 return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);  
  32.             }  
  33.   
  34.             public override bool Equals(object obj)  
  35.             {  
  36.                 // 1) 检查是否为空  
  37.                 if (obj == null)  
  38.                 {  
  39.                     return false;  
  40.                 }  
  41.   
  42.                 // 2) 如果是引用类型,就检查引用是否相等  
  43.                 if (ReferenceEquals(this, obj))  
  44.                 {  
  45.                     return true;  
  46.                 }  
  47.   
  48.                 // 3) 检查数据类型是否相等  
  49.                 if (this.GetType() != obj.GetType())  
  50.                 {  
  51.                     return false;  
  52.                 }  
  53.   
  54.                 // 4) 调用了一个指定了具体类型的辅助方法,  
  55.                 return Equals((Coordinate)obj);  
  56.             }  
  57.   
  58.             public bool Equals(Coordinate obj)  
  59.             {  
  60.                 // 5) 检查散列码是否相等  
  61.                 if (this.GetHashCode() != obj.GetHashCode())  
  62.                 {  
  63.                     return false;  
  64.                 }  
  65.   
  66.                 // 6) 如果基类重写了Equals(),就检查 base.Equals()  
  67.                 if (!base.Equals(obj))  
  68.                 {  
  69.                     return false;  
  70.                 }  
  71.   
  72.                 // 7) 比较每一个标识字段,判断是否相等  
  73.                 if ((this.X != obj.X) || (this.Y != obj.Y))  
  74.                 {  
  75.                     return false;  
  76.                 }  
  77.                 return true;  
  78.             }  
  79.   
  80.             // 8) 重写GetHashCode()  
  81.             // 这里偷个懒没有写什么Hash 算法  
  82.             public override int GetHashCode()  
  83.             {  
  84.                 return base.GetHashCode();  
  85.             }  
  86.   
  87.             // 9) 重写 == 和 != 运算符  
  88.             public static bool operator ==(Coordinate leftHandSide, Coordinate rightHandSide)  
  89.             {  
  90.                 if (ReferenceEquals(leftHandSide, null))  
  91.                 {  
  92.                     return ReferenceEquals(rightHandSide, null);  
  93.                 }  
  94.                 return leftHandSide.Equals(rightHandSide);  
  95.             }  
  96.   
  97.             public static bool operator !=(Coordinate leftHandSide, Coordinate rightHandSide)  
  98.             {  
  99.                 return !(leftHandSide == rightHandSide);  
  100.             }  
  101.         }  
  102.   
  103.         static void Main(string[] args)  
  104.         {  
  105.             Coordinate testToStingOverride = new Coordinate(10, 20);  
  106.   
  107.             Coordinate obj1 = new Coordinate(10, 20);  
  108.             Coordinate obj1Ref = obj1;  
  109.             Coordinate obj2 = new Coordinate(10, 20);  
  110.             Coordinate result = null;  
  111.   
  112.             double dResult = 0;  
  113.   
  114.             Console.WriteLine(testToStingOverride);  
  115.   
  116.             if (obj1.Equals(obj1Ref))  
  117.             {  
  118.                 Console.WriteLine("Obj1 and Obj1Ref are equal objects\n");  
  119.             }  
  120.   
  121.             // using Equals function  
  122.             if (obj1.Equals(obj2))  
  123.             {  
  124.                 Console.WriteLine("using Equal function : Obj1 and Obj2 are equal objects\n");  
  125.             }  
  126.             else  
  127.             {  
  128.                 Console.WriteLine("using Equal function : Obj1 and Obj2 are different objects\n");  
  129.             }  
  130.   
  131.             // using operator "=="  
  132.             if (obj1 == obj2)  
  133.             {  
  134.                 Console.WriteLine("using operator == : Obj1 and Obj2 are equal objects\n");  
  135.             }  
  136.             else  
  137.             {  
  138.                 Console.WriteLine("using operator == : Obj1 and Obj2 are different objects\n");  
  139.             }  
  140.          }  
  141.     }  
  142. }  



运算符重载

实现一个运算符的过程被称为运算符重载。好处是让程序更符合面向对象的概念,程序操作对象更加清晰。例如:如果没有运算符重载,两个对象相加时我们需要一个 add 函数 add(obj1, obj2)。如果重载了 + 运算符,这时就可以直接用 (obj1 + obj2),对对象进行操作了。


C# 中的运算符重载


一元,运算符
+, -, !, ~, ++, --, true, false




二元运算符
+, -, *, /, %, &, |, ^, <<, >>
代码实例:

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace _01ObjectOverloading  
  6. {  
  7.     class Program  
  8.     {  
  9.         class Coordinate  
  10.         {  
  11.             private int m_nX;  
  12.             private int m_nY;  
  13.   
  14.             public Coordinate(int x, int y)  
  15.             {  
  16.                 m_nX = x;  
  17.                 m_nY = y;  
  18.             }  
  19.   
  20.             public int X  
  21.             {   
  22.                 get {return m_nX;}  
  23.             }  
  24.             public int Y  
  25.             {  
  26.                 get { return m_nY; }  
  27.             }  
  28.   
  29.             public override string ToString()  
  30.             {  
  31.                 return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);  
  32.             }  
  33.   
  34.             //================================================  
  35.             //重载操作符 +  
  36.             public static Coordinate operator +(Coordinate leftHandSide, Coordinate rightHandSide)  
  37.             {  
  38.                 int x = leftHandSide.X + rightHandSide.X;  
  39.                 int y = leftHandSide.Y + rightHandSide.Y;  
  40.   
  41.                 Coordinate result = new Coordinate(x, y);  
  42.                 return result;  
  43.             }  
  44.         }  
  45.   
  46.         static void Main(string[] args)  
  47.         {  
  48.             Coordinate obj1 = new Coordinate(10, 20);  
  49.             Coordinate obj2 = new Coordinate(10, 20);  
  50.             Coordinate result = null;  
  51.   
  52.             double dResult = 0;  
  53.   
  54.   
  55.             // test overloading operator +  
  56.             Console.WriteLine("test overloading operator + ===========================\n");  
  57.             result = obj1 + obj2;  
  58.             Console.WriteLine(result);  
  59.   
  60.             Console.ReadKey();  
  61.         }  
  62.     }  
  63. }  



关系运算符
==, !=, <, >, <=, >=



条件运算符不能被重载
&&, ||



数组运算符不能被重载,但可以定义索引器
[]



转换运算符不能被重载,但可以定义隐式类型转换和显式类型转换运算符
()
代码实例:

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace _01ObjectOverloading  
  6. {  
  7.     class Program  
  8.     {  
  9.         class Coordinate  
  10.         {  
  11.             private int m_nX;  
  12.             private int m_nY;  
  13.   
  14.             public Coordinate(int x, int y)  
  15.             {  
  16.                 m_nX = x;  
  17.                 m_nY = y;  
  18.             }  
  19.   
  20.             public int X  
  21.             {   
  22.                 get {return m_nX;}  
  23.             }  
  24.             public int Y  
  25.             {  
  26.                 get { return m_nY; }  
  27.             }  
  28.   
  29.             public override string ToString()  
  30.             {  
  31.                 return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);  
  32.             }  
  33.   
  34.             //================================================  
  35.             //重载隐式转换运算符  
  36.             public static implicit operator double (Coordinate obj)  
  37.             {  
  38.                 return obj.X * obj.Y;  
  39.             }  
  40.   
  41.         }  
  42.   
  43.         static void Main(string[] args)  
  44.         {  
  45.             Coordinate testToStingOverride = new Coordinate(10, 20);  
  46.   
  47.             Coordinate obj1 = new Coordinate(10, 20);  
  48.   
  49.             Console.WriteLine("test overloading operator implicit() ===========================\n");  
  50.             dResult = (double)obj1;  
  51.             Console.WriteLine("dResult = (double)obj1 : X*Y    dResult = {0}", dResult);  
  52.   
  53.             Console.ReadKey();  
  54.         }  
  55.     }  
  56. }  



赋值运算符不能被重载
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=




下面的运算符不能被重载
=,  .,  ?:,  ->,  new,  is,  sizeof,  typeof

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多