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。

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

  • 相关阅读:
    DVWA 黑客攻防演练(十)反射型 XSS 攻击 Reflected Cross Site Scripting
    DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)
    DVWA 黑客攻防演练(八)SQL 注入 SQL Injection
    DVWA 黑客攻防演练(七)Weak Session IDs
    DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA
    DVWA 黑客攻防演练(五)文件上传漏洞 File Upload
    工作流表结构设计
    Visual Studio 2019尝鲜----新建空项目体验
    《使用CSLA 2019:CSLA .NET概述》原版和机译文档下载
    .NET快速开发平台的在线预览
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6784423.html
Copyright © 2011-2022 走看看