前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#对象比较,你用对了吗?几种方法?

C#对象比较,你用对了吗?几种方法?

作者头像
郑子铭
发布2023-12-26 19:05:22
1640
发布2023-12-26 19:05:22
举报

在 .NET 中使用 C# 时,对象比较(判等)可以通过多种方式进行,主要包括引用相等性比较和值相等性比较。理解这些不同的比较方法对于编写准确和高效的代码至关重要。值类型变量判断就是比较值是否相等,而引用类型的对象判断是否相等,一般是判断指定的对象是否是相同的实例。

1、Object.ReferenceEquals(static)

Object.ReferenceEquals 判断两个对象引用是否指向内存中的同一位置,若是使用Object.ReferenceEquals对值类型变量进行判等,'Object.ReferenceEquals‘ 总是返回False,需要特别注意一下。ReferenceEqual的方法签名及方法体,如下:

代码语言:javascript
复制
 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  public static bool ReferenceEquals(object objA, object objB)
  {
      return (objA == objB);
  }

从代码中可以看出传入值类型参数,会装箱成object类型,由于对象不是相同的实例,所以就会总是返回False

例如:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Object obj1 = new Object();
            Object obj2 = obj1;
            bool areEqual = Object.ReferenceEquals(obj1, obj2); // true
            Console.WriteLine(areEqual);
            Console.WriteLine(Object.ReferenceEquals(11, 11));//false
            Console.ReadKey();
        }
    }
}

2、Object.Equals(static)

Object.Equals用于比较两个对象的值或状态是否相等。可以重写 Equals 方法来定义自定义类型的相等逻辑。Object.Equals的方法签名及方法体,如下:

代码语言:javascript
复制
public static bool Equals(object objA, object objB)
 {
     return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
 }

例如:

代码语言:javascript
复制

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 10;
            bool areEqual = Object.Equals(a, b); // true
            Console.WriteLine(areEqual);
            object obj1 = new object();
            object obj2 = new object();

            areEqual = Object.Equals(obj1, obj2); // 返回 false,因为 obj1 和 obj2 指向不同的对象
            Console.WriteLine(areEqual);
            Console.ReadKey();
        }
    }
}

3、Operator操作符(==)

== 运算符可以用于比较对象。对于引用类型,默认行为是比较引用,但可以重载这些运算符来实现自定义的值比较。如下代码:

代码语言:javascript
复制


//添加下面代码到ThreeDPoint类定义之前
public static bool operator ==(ThreeDPoint a, ThreeDPoint b)
{
    // If both are null, or both are same instance, return true.
    if (System.Object.ReferenceEquals(a, b))
    {
        return true;
    }
    // If one is null, but not both, return false.
    if (((object)a == null) || ((object)b == null))
    {
        return false;
    }
    // Return true if the fields match:
    return a.x == b.x && a.y == b.y && a.z == b.z;
}
public static bool operator !=(ThreeDPoint a, ThreeDPoint b)
{
    return !(a == b);
}

需要注意的是,运算符 == 的重写中的常见错误是,重写的方法内还使用 (a == b)、(a == null) 或 (b == null) 来检查引用相等性。这会调用重载的运算符 ==,从而导致无限循环。应使用 ReferenceEquals 或将类型强制转换为 Object 来避免无限循环。

4、Instance.Equals

实例对象的Equals方法,这个其实和第二种Object.Equals(static)类似,只是参数只有一个,但是这个方法是在class内部继承Object的,是可以进行重写的。CLR会要求所有的类型都派生自Object,每个class内部都可以重写这个方法,如下:

代码语言:javascript
复制


public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        Point p = (Point)obj;
        return (X == p.X) && (Y == p.Y);
    }

    public override int GetHashCode()
    {
        return X ^ Y;
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Object.ReferenceEquals(static)
  • 2、Object.Equals(static)
  • 4、Instance.Equals
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档