09 C# 第九章 引用类型 ------ 重写Object成员和运算符重载

重写Object成员

重写 ToString()

代码实例:

namespace _01ObjectOverloading
{
    class Program
    {
        class Coordinate
        {
            private int m_nX;
            private int m_nY;

            public Coordinate(int x, int y)
            {
                m_nX = x;
                m_nY = y;
            }

            public override string ToString()
            {
                return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);
            }
        }

        static void Main(string[] args)
        {
            Coordinate testToStingOverride = new Coordinate(10, 20);

            Console.WriteLine(testToStingOverride);

            Console.ReadKey();
        }
    }
}


测试结果:
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())

using System;
using System.Collections.Generic;
using System.Text;

namespace _01ObjectOverloading
{
    class Program
    {
        class Coordinate
        {
            private int m_nX;
            private int m_nY;

            public Coordinate(int x, int y)
            {
                m_nX = x;
                m_nY = y;
            }

            public int X
            { 
                get {return m_nX;}
            }
            public int Y
            {
                get { return m_nY; }
            }

            public override string ToString()
            {
                return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);
            }

            public override bool Equals(object obj)
            {
                // 1) 检查是否为空
                if (obj == null)
                {
                    return false;
                }

                // 2) 如果是引用类型,就检查引用是否相等
                if (ReferenceEquals(this, obj))
                {
                    return true;
                }

                // 3) 检查数据类型是否相等
                if (this.GetType() != obj.GetType())
                {
                    return false;
                }

                // 4) 调用了一个指定了具体类型的辅助方法,
                return Equals((Coordinate)obj);
            }

            public bool Equals(Coordinate obj)
            {
                // 5) 检查散列码是否相等
                if (this.GetHashCode() != obj.GetHashCode())
                {
                    return false;
                }

                // 6) 如果基类重写了Equals(),就检查 base.Equals()
                if (!base.Equals(obj))
                {
                    return false;
                }

                // 7) 比较每一个标识字段,判断是否相等
                if ((this.X != obj.X) || (this.Y != obj.Y))
                {
                    return false;
                }
                return true;
            }

            // 8) 重写GetHashCode()
            // 这里偷个懒没有写什么Hash 算法
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }

            // 9) 重写 == 和 != 运算符
            public static bool operator ==(Coordinate leftHandSide, Coordinate rightHandSide)
            {
                if (ReferenceEquals(leftHandSide, null))
                {
                    return ReferenceEquals(rightHandSide, null);
                }
                return leftHandSide.Equals(rightHandSide);
            }

            public static bool operator !=(Coordinate leftHandSide, Coordinate rightHandSide)
            {
                return !(leftHandSide == rightHandSide);
            }
        }

        static void Main(string[] args)
        {
            Coordinate testToStingOverride = new Coordinate(10, 20);

            Coordinate obj1 = new Coordinate(10, 20);
            Coordinate obj1Ref = obj1;
            Coordinate obj2 = new Coordinate(10, 20);
            Coordinate result = null;

            double dResult = 0;

            Console.WriteLine(testToStingOverride);

            if (obj1.Equals(obj1Ref))
            {
                Console.WriteLine("Obj1 and Obj1Ref are equal objects\n");
            }

            // using Equals function
            if (obj1.Equals(obj2))
            {
                Console.WriteLine("using Equal function : Obj1 and Obj2 are equal objects\n");
            }
            else
            {
                Console.WriteLine("using Equal function : Obj1 and Obj2 are different objects\n");
            }

            // using operator "=="
            if (obj1 == obj2)
            {
                Console.WriteLine("using operator == : Obj1 and Obj2 are equal objects\n");
            }
            else
            {
                Console.WriteLine("using operator == : Obj1 and Obj2 are different objects\n");
            }
         }
    }
}



运算符重载

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


C# 中的运算符重载


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




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

using System;
using System.Collections.Generic;
using System.Text;

namespace _01ObjectOverloading
{
    class Program
    {
        class Coordinate
        {
            private int m_nX;
            private int m_nY;

            public Coordinate(int x, int y)
            {
                m_nX = x;
                m_nY = y;
            }

            public int X
            { 
                get {return m_nX;}
            }
            public int Y
            {
                get { return m_nY; }
            }

            public override string ToString()
            {
                return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);
            }

            //================================================
            //重载操作符 +
            public static Coordinate operator +(Coordinate leftHandSide, Coordinate rightHandSide)
            {
                int x = leftHandSide.X + rightHandSide.X;
                int y = leftHandSide.Y + rightHandSide.Y;

                Coordinate result = new Coordinate(x, y);
                return result;
            }
        }

        static void Main(string[] args)
        {
            Coordinate obj1 = new Coordinate(10, 20);
            Coordinate obj2 = new Coordinate(10, 20);
            Coordinate result = null;

            double dResult = 0;


            // test overloading operator +
            Console.WriteLine("test overloading operator + ===========================\n");
            result = obj1 + obj2;
            Console.WriteLine(result);

            Console.ReadKey();
        }
    }
}



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



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



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



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

using System;
using System.Collections.Generic;
using System.Text;

namespace _01ObjectOverloading
{
    class Program
    {
        class Coordinate
        {
            private int m_nX;
            private int m_nY;

            public Coordinate(int x, int y)
            {
                m_nX = x;
                m_nY = y;
            }

            public int X
            { 
                get {return m_nX;}
            }
            public int Y
            {
                get { return m_nY; }
            }

            public override string ToString()
            {
                return string.Format("Coordinate:  x= {0}, y={1}", m_nX, m_nY);
            }

            //================================================
            //重载隐式转换运算符
            public static implicit operator double (Coordinate obj)
            {
                return obj.X * obj.Y;
            }

        }

        static void Main(string[] args)
        {
            Coordinate testToStingOverride = new Coordinate(10, 20);

            Coordinate obj1 = new Coordinate(10, 20);

            Console.WriteLine("test overloading operator implicit() ===========================\n");
            dResult = (double)obj1;
            Console.WriteLine("dResult = (double)obj1 : X*Y    dResult = {0}", dResult);

            Console.ReadKey();
        }
    }
}



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




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




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值