c#中 ==与equals有什么区别
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 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。
好了,下面是考题,相信答案大家都知道了。
Console.WriteLine((2 + 2) == 4);
object s = 1;
object t = 1;
Console.WriteLine(s == t);
string a = "hello";
string b = String.Copy(a);
string c = "hello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);
Console.WriteLine((object)a == (object)c);
答案:TRUE, FALSE, TRUE, FALSE, TRUE
操作符“==”在值类型情况下表示是否值相等.
equals 判断是否是同一个对象的引用.
string的==和equals都是比较值。
c#中 ==与equals有什么区别的更多相关文章
- Java中“==”与equals方法的区别
1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...
- C#中==与Equals方法的区别
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace Console ...
- c#中 ==与equals有什么区别【转】
转至http://www.zybang.com/question/2263895f201ffec6c68b6c304ac4cd61.html 对于值类型.引用类型来说比较过程怎样的?using Sys ...
- java中“==”和equals方法的区别,再加上特殊的String引用类型
==和equals的区别: 1.==是运算符,而equals是基类Object定义的一个方法,并且equals使用==定义的 2.进行比较时,分为 基本数据类型 的比较和 引用数据类型 的比较 ...
- java中的equals与==的区别
equals是Object类的公共方法,方法内部是用==实现的.但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同.而==是比较地址, ...
- Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法
一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...
- java中 ==与equals 有什么区别?
1.==既可以比较基本类型变量,又可比较引用类型变量,而equals只能比较引用类型变量: 2.equals方法支持重写,如果未重写equals方法,则比较引用变量时与==都是比较变量所指向的对象地址 ...
- Java中"String.equals()“和"=="的区别
Do NOT use the `==`` operator to test whether two strings are equal! It only determines whether or n ...
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)
Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例 原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...
随机推荐
- WPF 绑定
WPF里分三种Binding:Binding, PriorityBinding, MultiBinding,这三种Binding的基类都是BindingBase,而BindingBase又继承于Mar ...
- [LeetCode82]Remove Duplicates from Sorted List II
题目: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct ...
- UI标签库的话题:JEECG智能开发平台 BaseTag(样式表和JS标签的引入)
UI标签库专题一:JEECG智能开发平台 BaseTag(样式表和JS引入标签) 1.BaseTag(样式表和JS引入标签) 1.1. 演示样例 <t:base type="jquer ...
- POJ 2405 Beavergnaw (计算几何-简单的问题)
Beavergnaw Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6203 Accepted: 4089 Descri ...
- Android - 数据存储 -在SQL数据库中保存数据
对于重复的或结构化的数据,保存到数据库中是很好的选择,比如联系人信息.这里假设你对SQL数据库大体上了解然后帮助你学习Android上的SQLite数据库.在Android数据库上需要用到的API可以 ...
- ORACLE profile列4 --CREATE PROFILE
这个博客是ORACLE profile系列第四部分.主要说一下,假设你创建profile而使用profile资源和password控制 CREATE PROFILE Note: Oracle reco ...
- Mongodb 之insert瞬时完成,测试数据---飞天博客
这几天看mongdb官方网站,然后将执行数据.突然,我发现,该数据确实很强大,在这里说话数据.我用普通的pc机,amd双核 2.7GHz,4G内存,当然,当系统不只是在测试作为数据库server的.同 ...
- JAVA 跑马灯文字效果
JAVA跑马灯文字效果的实现: 1. 首先创建一个继承JFrame类的HorseRaceLightTextFrame窗体类,代码如下: package com.example.horseracelig ...
- Cocos2d-X中实现批处理精灵
使用普通方法实现批处理精灵 在Sprite.h中加入以下的代码 #ifndef __Sprite_SCENE_H__ #define __Sprite_SCENE_H__ #include " ...
- MVC5 Entity Framework学习之实现继承
之前你已经学习了怎样处理并发异常,在本节中你将学习怎样实现继承. 在面向对象的编程中,你能够使用继承来重用代码.接下来你将改动Instructor和Student类,让它们派生自Person基类,该基 ...