zoukankan      html  css  js  c++  java
  • C#比較对象的相等性

       对于相等的机制全部不同,这取决于比較的是引用类型还是值类型。以下分别介绍引用类型和值类型的相等性。

    1.比較引用类型的相等性

       System.Object定义了三种不同的方法,来比較对象的相等性:ReferenceEquals()和两个版本号的Equals()。再加上比較运算符(==)。实际上有4种进行比較相等的方式。

    1.1 ReferenceEquals()方法

    命名控件: System

    程序集:mscorlib.dll

    语法:public static bool ReferenceEquals(Object objA, Object objB)

    能够看出ReferenceEquals()是一个静态方法,确定指定的Object实例是否是同样的实例。作为静态方法。所以不能重写。

    1.1.1 使用ReferenceEquals()方法比較值类型

    int int1 = 3;

    bool B1 = Object.ReferenceEquals(int1, int1);//B1为false

        因为objA和objB是值类型,首先进行装箱。然后传递给ReferenceEquals()方法。这意味着,即使objA和objB表示值类型的同一个实例,ReferenceEquals()方法也返回false。

    1.1.2 使用ReferenceEquals()方法比較字符串

    String s1 = "String1";

    String s2 = "String1";

    bool B2 = Object.ReferenceEquals(s1, s2);//true

    String suffix = "A";

    String s3 = "String" + suffix;

    String s4 = "String" + suffix;

    bool B3 = Object.ReferenceEquals(s3, s4);//false

        当比較字符串时 假设 objA 和 objB 是字符串,假设该字符串会暂留,ReferenceEquals 方法返回 true。 它不运行值相等測试。

    在以下的演示样例中。由于它们是一个暂存的字符串的两个实例,s1 和 s2 相等。 可是,s3 和 s4 不相等,由于虽然它们是具有同样的字符串值。字符串不会暂留。

    1.1.3 使用ReferenceEquals()比較两个对象

    object o = null;

    object p = null;

    object q = new Object();

    bool B4 = Object.ReferenceEquals(o, p);//true

    p = q;

    bool B5 = Object.ReferenceEquals(p, q);//true

    bool B6 = Object.ReferenceEquals(o, p);//false

    1.2 Equals()方法

    1.2.1 虚拟的Equals()方法

    命名空间: System

    程序集:mscorlib(在mscorlib.dll中)

    语法:public virtual bool Equals(Object obj)

        Equals()虚拟版本号的System.Object实现代码也比較引用。

    但由于这种方法是虚拟的。所以能够在自己的类中重写它。按值来比較对象。

    特别是假设希望类的实例用作字典中的键,就须要重写这种方法,以比較值。否则。依据重写Object.GetHashCode()的方式。包括对象的字典类要么不工作,要么工作的效率很低。在重写Equals()方法时要注意,重写的代码不会抛出异常。这是由于假设抛出异常。字典类就会出问题,一些在内部调用这种方法的.NET基类也可能出问题。

        Equals 是一个虚方法。同意不论什么类重写事实上现。

    表示某个值(本质上能够是不论什么值类型)或一组值(如复数类)的不论什么类都应该重写 Equals。假设类型要实现 IComparable,则它应该重写 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。

        Equals 的新实现不应该引发异常。建议重写 Equals 的不论什么类同一时候也重写 System.Object.GetHashCode。

    除了实现 Equals(对象)外。还建议全部的类为自己的类型实现 Equals(类型)以增强性能。

    比如:

    class TwoDPoint : System.Object

    {

    public readonly int x, y;

    public TwoDPoint(int x, int y) //constructor

    {

    this.x = x;

    this.y = y;

    }

    public override bool Equals(System.Object obj)

    {

    // If parameter is null return false.

    if (obj == null)

    {

    return false;

    }

    // If parameter cannot be cast to Point return false.

    TwoDPoint p = obj as TwoDPoint;

    if ((System.Object)p == null)

    {

    return false;

    }

    // Return true if the fields match:

    return (x == p.x) && (y == p.y);

    }

    public bool Equals(TwoDPoint p)

    {

    // If parameter is null return false:

    if ((object)p == null)

    {

    return false;

    }

    // Return true if the fields match:

    return (x == p.x) && (y == p.y);

    }

    public override int GetHashCode()

    {

    return x ^ y;

    }

    }

    1.2.2 静态的Equals()方法

    命名空间: System

    程序集:mscorlib(在mscorlib.dll中)

    语法:public static bool Equals(Object objA, Object objB)

    Dog m1 = new Dog("Alaskan Malamute");

    Dog m2 = new Dog("Alaskan Malamute");

    Dog g1 = new Dog("Great Pyrenees");

    Dog g2 = g1;

    Dog d1 = new Dog("Dalmation");

    Dog n1 = null;

    Dog n2 = null;

    Console.WriteLine("null = null: {0}", Object.Equals(n1, n2));//true

    Console.WriteLine("null Reference Equals null: {0} ", Object.ReferenceEquals(n1, n2));//true

    Console.WriteLine("{0} = {1}: {2}", g1, g2, Object.Equals(g1, g2));//true

    Console.WriteLine("{0} Reference Equals {1}: {2} ", g1, g2, Object.ReferenceEquals(g1, g2));//true

    Console.WriteLine("{0} = {1}: {2}", m1, m2, Object.Equals(m1, m2));//true

    Console.WriteLine("{0} Reference Equals {1}: {2} ", m1, m2, Object.ReferenceEquals(m1, m2));//false

    Console.WriteLine("{0} = {1}: {2}", m1, d1, Object.Equals(m1, d1)); //false Console.WriteLine("{0} Reference Equals {1}: {2}", m1, d1, Object.ReferenceEquals(m1, d1)); //false 

        静态 Equals(Object, Object) 方法指示两个对象。objA 和 objB,是否相等

        它确定两个对象是否表示同一对象引用。 假设成功,该方法返回 true. 这測试与调用 ReferenceEquals 方法等效。 另外。假设 objA 和 objB 都为 null,则方法返回 true。

    它确定 objA 或 objB 是否 null。 假设是这样。则返回 false。

        假设两个对象不表示同一对象引用,且均不为 null,它调用 objA。

    Equals(objB) 而且返回结果。

    这意味着。假设 objA 重写 Object.Equals(Object) 方法,该重写调用。

    1.3 比較运算符(==)

        对于引用类型,== 默认的行为与ReferenceEquals的行为同样,仅有两个对象指向同一个Reference的时候才返回true。可是.NET Framework中的类非常多对==进行了重载,比如String类的==与Equals的行为同样。推断两个字符串的内容是否相等。所以在应用中。对于 系统定义的引用类型建议不要使用==操作符,以免程序出现与预期不同的执行结果。

    重载的运算符 == 实现不应引发异常。重载运算符 == 的不论什么类型还应重载运算符 !=。

    比如:

    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);

    }

    2.比較值类型的相等性

        在比較值类型的相等时,採用与引用类型同样的规则:ReferenceEquals()用于比較引用,Equals()用于比較值,比較运算发能够看做是一个中间项。但最大的差别是值类型须要装箱。才干把他们转换为引用。

    ReferenceEquals()在应用于值类型时。总是返回false。

    由于调用这种方法,须要装箱。

  • 相关阅读:
    oracle角色、权限和用户
    轻松解决oracle11g 空表不能exp导出的问题
    oracle 11g杀掉锁的sql
    oracle创建表空间
    js 读取xml文件
    oracle decode函数使用方
    oracle的触发器的实战使用
    oracle获取日期的数字格式,24小时制
    oracle判断表中的某个字段是否为数字trim+translate函数或regexp_like函数
    java String字符串操作 字符串加密等
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6784423.html
Copyright © 2011-2022 走看看