C#相等类型分析

本文介绍了C#中相等性的两种类型:引用相等(ReferenceEquals)和值相等(Equals)。引用相等比较对象的内存地址,值相等则关注对象内容。ReferenceEquals主要用于引用类型,而Equals在值类型和引用类型中有所不同。对于自定义的引用类型,通常需要重载Equals方法来实现值相等的比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    C#中的相等有两种类型:引用相等(ReferenceEquals)和值相等(Equals)。值相等就是说两个对象包含相同的值。而引用相等则比较的是两个对象的引用是否是同一个对象。也就是说,如果ReferenceEquals为True,则Equals必然为True,反过来就不一定了。

    引用相等(ReferenceEquals)在object类静态实现,其原型是public static bool ReferenceEquals(object objA, object objB)。针对值类型,首先是将值类型装箱变为引用类型(地址肯定不同),在比较地址是否相等,因此返回的总是false,所以该函数主要针对引用类型比较。

   object类还实现另外两个Equal函数,分别为 public static bool Equals(object objA, object objB),public virtual bool Equals(object obj),针对值类型,没什么可说的,其它值一样就认为是相等的。对于引用类型,先看下面的例子:

 public class test
    {
        int value  = 1;
    }
    class Program
    {
        static void Main(string[] args)
        {
            test a = new test();
            test b = new test();
            Console.WriteLine(a.Equals(b));
            Console.WriteLine(test.Equals(a,b));
            Console.WriteLine(b.Equals(a));
            Console.WriteLine(a==b);
            Console.ReadKey();

        }
    }

返回的全是false,所以针对引用类型,比较的时地址是否一致。

对于自定义的引用类型,如果想要判断值相等,则必须重载Equals(object obj),.NET库中字符串就是重载了该函数,如:

string strA = "Hello";
string strB = string.Copy(strA);
Console.WriteLine(strA == strB);         //True
Console.WriteLine(strA.Equals(strB));    //True
Console.WriteLine(object.Equals(strA, strB));    //True
Console.WriteLine(object.ReferenceEquals(strA, strB));       //False

先不考虑==号,看几个Equals的表现,Equals是要实现值相等比较的效果的,.net 在实现string的时候就重写了Equals(object) ,并添加重载函数Equals(string) ,因此两个比较才会返回True。而不实现这两个函数的后果就是都返回False,无法符合Equals函数应有的作用。

MSDN上Equals函数实现的保证:

Equals 的新实现应该遵循 Equals 的所有保证:

  • x.Equals(x) 返回 true。
  • x.Equals(y) 与 y.Equals(x) 返回相同的值。
  • 如果 (x.Equals(y) && y.Equals(z)) 返回 true,则 x.Equals(z) 返回 true。
  • 只要不修改 x 和 y 所引用的对象,x.Equals(y) 的后续调用就返回相同的值。
  • x.Equals (null) 返回 false(仅非空值类型。有关更多信息,请参见可空类型(C# 编程指南)。)

由此看来,对于之前我的需求:比较两个自定义类的内容是否相同,还是应该重写Equals(Object),并建议重载对自己的类的实现Equals(MyClass)

而对于==运算符的解释为:拖过判断两个引用是否指示同一对象来测试是否相等。也就是引用相等了,可对于上面对string的测试,RefrenceEquals为False时,==却返回的True,这是因为还有这么一条:当类型不可变(即实例中包含的数据不可更改)时,通过重载运算符== 来比较值是否相等而不是比较引用是否相等可能会很有用。(这里和java不同,java的==就是用来比较引用是否相等的,而且java也不允许算符重载)。

我们大部分情况下写的自定义类都是可变的,所以一般用不到也不应该对==进行重载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值