DotNet_运算符重载,引用,比较

抛出问题:

  1 程序员A在某天Debug代码的时候发现了一个不可思议的问题:从服务端获取两次数据组装的对象 DataObj1,DataObj2,竟然出现 DataObj1 == DataObj2 返回true的情况,两个不同的实例,引用自然而然是不同的,为什么?

  2 程序员B看到C#的Object中定义了一个 public staticbool ReferenceEquals(object objA, object objB) 静态方法,这个是不是多余的?如果Object A,B,我要比较引用不是很直接吗? A == B

解答时间

  代码:Object a, b;

    这里的a和b确实是对Object对象的引用,这一点是没有任何异议的

  但是

  a == b;

      的具体含义不能绝对认为这个就是针对 a 和 b的引用比较,因为DotNet/C#支持操作符的重载,关键字是 operator

  a == b 的具体含义依赖于 == 这个操作符的实现:

    1)对于引用类型这个操作符的默认行为是 比较对象的引用

    2)对于值类型这个操作符的默认行为是按照值进行比较

  另外,在重载 == 或者 != 操作符一定需要明确的是一定需要一起重载,成对出现。

  了解了上面的点,上面的问题就很好解决了:

  1)相同类型的不同实例,其引用一定不同,但是使用 == 返回true,很显然,该类型重载了 == 和 !=,这个很好验证可以检查类型的实现即可。

  2)当我们确实希望按照引用进行比较,那么调用 ReferrecneEquals 一定保证比较的实现是基于引用的,这样一来就看出这个方法的独特用处了。

  后面附一个简单的重载实例:

  

using System;
using System.Collections.Generic;
using System.Linq;

namespace EqualImplement
{
    class SampleObject
    {
        private Int32 m_Age;
        private Int32 m_Count;

        public SampleObject(
            Int32 i_age,
            Int32 i_count
            )
        {
            m_Age = i_age;
            m_Count = i_count;
        }

        private static bool IsNull(
            Object i_so
            )
        {
            return ReferenceEquals(i_so, null);
        }


        public override bool Equals(
            Object i_obj
            )
        {
            if (!IsNull(i_obj))
            {
                return base.Equals(i_obj);
            }

            return Equals(i_obj as SampleObject);
        }

        private bool Equals(
            SampleObject i_obj
            )
        {
            return (i_obj.Age == m_Age) && (i_obj.Count == m_Count);
        }

        public Int32 Age
        {
            get
            {
                return m_Age;
            }
        }

        public Int32 Count
        {
            get
            {
                return m_Count;
            }
        }

        public override int GetHashCode()
        {
            return m_Age.GetHashCode();
        }

        public static bool operator ==(
            SampleObject i_so1,
            SampleObject i_so2
            )
        {
            if (!IsNull(i_so1))
            {
                return i_so1.Equals(i_so2);
            }

            if (!IsNull(i_so2))
            {
                return i_so2.Equals(i_so1);
            }

            return true;
        }

        public static bool operator !=(
            SampleObject i_so1,
            SampleObject i_so2
            )
        {
            if (!IsNull(i_so1))
            {
                return (!i_so1.Equals(i_so2));
            }

            if (!IsNull(i_so2))
            {
                return (!i_so2.Equals(i_so1));
            }

            return false;
        }
    }
}
View Code

  调用:

 

using System;
using System.Collections.Generic;
using System.Linq;

namespace EqualImplement
{
    class Program
    {
        static void Main(string[] args)
        {
            var so1 = new SampleObject(12, 14);
            var so2 = new SampleObject(12, 14);

            Console.WriteLine("so1 == so2 ?" + ((so1 == so2) ? "Y" : "N"));
            Console.WriteLine("so1 and so2 have the same referrence ? " + ReferenceEquals(so1, so2));

            Console.ReadKey();
        }
    }
}
View Code

 

  输出结果类似:

  so1 == so2 ?Y
  so1 and so2 have the same referrence ? False

  

  

    

  

转载于:https://www.cnblogs.com/rainychan/p/4877185.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值