转至http://www.zybang.com/question/2263895f201ffec6c68b6c304ac4cd61.html

对于值类型、引用类型来说比较过程怎样的?
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public Person(string name)
{
this.name = name;
}
}
class Program
{
static void Main(string[] args)
{
string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
Console.WriteLine(a == b);
Console.WriteLine(a.Equals(b));
object g = a;
object h = b;
Console.WriteLine(g == h);
Console.WriteLine(g.Equals(h));
Person p1 = new Person("jia");
Person p2 = new Person("jia");
Console.WriteLine(p1 == p2);
Console.WriteLine(p1.Equals(p2));
Person p3 = new Person("jia");
Person p4 = p3;
Console.WriteLine(p3 == p4);
Console.WriteLine(p3.Equals(p4));
Console.ReadLine();
}
}
}
答案为何为true true false true false false true true
因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
"==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
"equals" : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。
因此在上面的例子中,第一对输出 ,字符串a和字符串b的两个比较是相等的。
对于 第二对输出 object g = a 和object h = b , 在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:
string a="aa";
string b="aa";
则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。
MSDN中就有介绍啊:
下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:
每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。
每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。
每次实现 IComparable 时都要重写 Equals 方法。
实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( ) 运算符的运算符重载。
不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。
有关 Equals 方法的相关信息,请参见实现 Equals 方法。
在值类型中实现相等运算符 (==)
大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。
应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。
每次重写 Equals 方法时都实现相等运算符 (==)。
在引用类型中实现相等运算符 (==)
大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。
如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。

c#中 ==与equals有什么区别【转】的更多相关文章

  1. Java中“==”与equals方法的区别

    1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...

  2. C#中==与Equals方法的区别

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace Console ...

  3. c#中 ==与equals有什么区别

    对于值类型.引用类型来说比较过程怎样的? using System;using System.Collections.Generic;using System.Text; namespace Cons ...

  4. java中“==”和equals方法的区别,再加上特殊的String引用类型

    ==和equals的区别: 1.==是运算符,而equals是基类Object定义的一个方法,并且equals使用==定义的 2.进行比较时,分为  基本数据类型  的比较和  引用数据类型 的比较 ...

  5. java中的equals与==的区别

    equals是Object类的公共方法,方法内部是用==实现的.但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同.而==是比较地址, ...

  6. Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法

    一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...

  7. java中 ==与equals 有什么区别?

    1.==既可以比较基本类型变量,又可比较引用类型变量,而equals只能比较引用类型变量: 2.equals方法支持重写,如果未重写equals方法,则比较引用变量时与==都是比较变量所指向的对象地址 ...

  8. Java中"String.equals()“和"=="的区别

    Do NOT use the `==`` operator to test whether two strings are equal! It only determines whether or n ...

  9. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

随机推荐

  1. oracle 变量声明 初始化 赋值

    DECLARE sname VARCHAR2(20); BEGIN sname:='xxx'; sname:=sname||' and tom'; dbms_output.put_line(sname ...

  2. MFC之常用控件(四)

    常用控件主要包括:静态文本框.编辑框.单选按钮.复选框.分组框.列表框.组合框.图片控件.列表控件.树形控件和进度条控件等等.本节教程先来讲解静态文本框的使用. 控件的通知消息 在将静态文本框的使用之 ...

  3. Object转换为json格式

    public String toJSONString(Object obj)     {              SerializeWriter serializewriter = new Seri ...

  4. windows10 环境下theano安装

    前言:我用的是 Anaconda2 安装python 1. 在Anaconda prompt中输入 conda install mingw libpython 2. 添加环境变量 C:\Anacond ...

  5. 优化Linux内核参数/etc/sysctl.conf sysctl 《高性能Linux服务器构建实战:运维监控、性能调优与集群应用》

    优化Linux内核参数/etc/sysctl.conf  sysctl  <高性能Linux服务器构建实战:运维监控.性能调优与集群应用> http://book.51cto.com/ar ...

  6. Android --Spinner--自定义Spinner

    主要参考博客Android 实现自定义Spinner 1.Spinner样式 <?xml version="1.0" encoding="utf-8"?& ...

  7. 框架基础——全面解析Java注解

    为什么学习注解? 学习注解有什么好处? 学完能做什么? 答:1. 能够读懂别人写的代码,特别是框架相关的代码: 2. 让编程更加简洁,代码更加清晰: 3. 让别人高看一眼. spring.mybati ...

  8. 高级选择器querySelector和querySelectorAll

    Javascript新提供的querySelector和querySelectorAll方法,是仿照CSS选择器功能编写的 querySelector 功能:该方法返回满足条件的单个元素.按照深度优先 ...

  9. Moment.js学习(一)源代码

    本篇主要是学习Moment.js.类库源代码如下: 2.4版本. //! moment.js //! version : 2.4.0 //! authors : Tim Wood, Iskren Ch ...

  10. 查看PostgreSQL版本,编译器版本号

    [postgres@localhost bin]$ ./psql -h localhostpsql (9.4.5)Type "help" for help. postgres=# ...