【转】C#中的==、Equal、ReferenceEqual
【转】C#中的==、Equal、ReferenceEqual
1. ReferenceEquals, == , Equals
Equals , == , ReferenceEquals都可以用于判断两个对象的个体是不是相等。
a) ReferenceEquals
ReferenceEquals是Object的静态方法,用于比较两个引用类型的对象是否是对于同一个对象的引用。对于值类型它总是返回false。(因为Box以后的对象总是不同的,hehe)
b) ==是一个可以重载的二元操作符,可以用于比较两个对象是否相等。
对于内置值类型,==判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false。例如:
Int a = 100;
Double b =100;
If(a == b)
Console.WriteLine(“equal supports compare between different types!”);
上面这段程序将会输出:
equal supports compare between different types!
而对于用户定义的值类型,如果没有重载==操作符,==将是不能够使用的。例如:
Struct Userstruct1;
Userstruct1 a;
Userstruct1 b;
If(a == b)
Console.WriteLine(“can == reach this far?”)
上面的这段代码是不能够通过编译的。可以通过重载使==作用于用户定义的值类型。
对于引用类型,== 默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时候才返回true。但是.NET Framework中的类很多对==进行了重载,例如String类的==与Equals的行为相同,判断两个字符串的内容是否相等。所以在应用中,对于 系统定义的引用类型建议不要使用==操作符,以免程序出现与预期不同的运行结果。
c) Equals 作为Object内置方法,Equals支持对于任意两个CTS对象的比较。
Equals它有静态方法和可重载的一个版本,下面的程序片断解释了这两个方法的用法,
int a = 5;
int b = 5;
If(Object.Equals(a ,b))
// you can also use if(a.Equals(b))
{
Console.WriteLine(“a is equal to b”);
}
事实上,这两个版本的结果完全相同,如果用户重载了Equals,调用的都是用户重载后的Equals。Equals的静态方法的好处是可以不必考虑用于比较的对象是否为null。
Equals方法对于值类型和引用类型的定义不同,对于值类型,类型相同,并且数值相同(对于struct的每个成员都必须相同),则Equals返回 true,否则返回false。而对于引用类型,默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时 候才返回true。可以根据需要对Equals进行重载,例如String类的Equals用于判断两个字符串的内容是否相等。
StringBuilder a = new StringBuilder();
a.Append("the test a");
String s1 = a.ToString();
String s2 = "the test a";
if (s2 == s1)
Console.WriteLine("== returns true");
if (Object.Equals(s2, s1))
{
Console.WriteLine("equals returns true");
}
if (Object.ReferenceEquals(s2, s1))
{
Console.WriteLine("ReferenceEquals returns true");
}
这个实例将输出:
== returns true
equals returns true
注:对于String类,直接声明s1 = “the test a”的话,输出结果将包含 "ReferenceEquals returns true",
因为默认的,String对于声明的相同的字符串在堆上只保留一个Copy,所以s1与s2将会指向相同的Reference
在C#中,有多种比较方法,有referenceequal,equals,equalsto,但他们之间是有细微差别的。
referenceequal的实例
class MyClass {
static void Main() {
object o = null;
object p = null;
object q = new Object();
Console.WriteLine(Object.ReferenceEquals(o, p));
p = q;
Console.WriteLine(Object.ReferenceEquals(p, q));
Console.WriteLine(Object.ReferenceEquals(o, p));
}
如果要是对象都指向空引用,那么它返回true,另外,p=q;这个赋值语句,对于值类型来说,只是把地址复制给了p,并没有深拷贝。所以当比较引用时,返回true。如果比较o.equals(p),那么编译器会报错,因为equals方法不能比较null的情况。正因为如此,referenceequals方法才不受开发人员欢迎。另外,equals为实例的虚方法,referenceequals为静态方法。基元类型的==,就是操作符重载,使用的 equals方法判等。当然,还有一个equals的静态方法,静态equals与实例equals方法的唯一区别是:实例equals在对2个进行比较时,如果有一个为null,或者都是null,就会抛出异常,但静态equals方法不会,静态equals方法首先对2者检查是否为null,如果有为null的情况,就返回false,如果没有null,那么就调用实例equals方法来进行比较。
memberwiseclone()翻译为成员智能复制,呵呵,为啥智能,我就讲讲。智能就在它区别对待值类型和引用类型。
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
例如,考虑一个名为 X 的对象,该对象引用对象 A 和 B。对象 B 又引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。与此相对照,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2,它们分别是 A 和 B 的副本。B2 又引用新对象 C2,C2 是 C 的副本。
关于深拷贝和浅拷贝,深拷贝就是创建一个一摸一样的对象,浅拷贝的话仍然是同一个对象,但是却有2个计数器,2个强引用指向它。
【转】C#中的==、Equal、ReferenceEqual的更多相关文章
- java中 == 与 equal 的区别
http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html String str1 = new String("s ...
- java中“==”和equal区别
8个月以后就要正式找工作啦,我觉得现在是时候花时间好好深入研究一下以前比较混肴的知识.这就当作是自我成长的第一步! 对于String中的“equal方法”和“==”一直有点混肴,今天重新看了一下他们两 ...
- String中的“equal方法”和“==”
二话不说,先来说下重写的事情: 在Java中,String .Math.还有Integer.Double....等这些封装类重写了Object中的equals()方法,让它不再比较其对象在内存中的地址 ...
- java 中的equal和"=="
先看一段代码 String str1 = new String("str"); String str2 = new String("str"); System. ...
- Java Script 中 ==(Equal) 和 === (Identity Equal) 的区别和比较算法逻辑
判断两个变量是否相等在任何编程语言中都是非常重要的功能. JavaScript 提供了 == 和 === 两种判断两个变量是否相等的运算符,但我们开始学习的时候 JavaScript 的时候,就被一遍 ...
- 对比C#中==与equal方法
C#中equal与==的区别 收藏 对于值类型,如果对象的值相等,则相等运算符 (==) 返回 true,否则返回 false.对于string 以外的引用类型,如果两个对象引用同一个对象,则 == ...
- C# 中==和Equal的区别
http://new-fighter.iteye.com/blog/1634800 今天突然看到一种情况,颠覆了我对这比较使用方法的判断. 于是开始在网上找资料,但几乎都是Java的,好不容易找到一个 ...
- java中==与equal()方法的区别
==比较的是对象的地址,也就是是否是同一个对象: equal比较的是对象的值. Integer r1 = new Integer(900);//定义r1整型对象Integer r2 = new Int ...
- java中 == 与 equal区别 转
java中的数据类型,可分为两类:1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==) ...
- java中==与equal()的区别
==和equal()都是用来判断两个变量是否相等的. (1)如果两个变量是基本类型变量,且都是数值型的(不一定数据类型相同),只要是值相同,将返回true; (2)如果两个变量是引用型变量,只有它们指 ...
随机推荐
- hdoj1465【错排公式(直接水过)】
//注意会爆 int #include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigne ...
- Incorrect string value: '\xE8\x8B\x8F\xE6\x99\xA8...' for column 'user_name' at row 1
前端插入数据的时候报如下错误: Incorrect string value: '\xE8\x8B\x8F\xE6\x99\xA8...' for column 'user_name' at row ...
- Python入门小练习 003 利用cookielib模拟登录获取账户信息
为了方便, 使用chinaunix的账户获取账户主题. 有些网站可能需要验证码, 找一些不用验证码的网站 下面 ****** 很多个星号的均为私密信息, 所以用星号代替 #!/usr/bin/pyt ...
- Python 教程资源
1.廖雪峰的官方网站 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386 ...
- Lightoj 1044 - Palindrome Partitioning (DP)
题目链接: Lightoj 1044 - Palindrome Partitioning 题目描述: 给一个字符串,问至少分割多少次?分割出来的子串都是回文串. 解题思路: 先把给定串的所有子串是不 ...
- Magic Numbers CodeForces - 628D
Magic Numbers CodeForces - 628D dp函数中:pos表示当前处理到从前向后的第i位(从1开始编号),remain表示处理到当前位为止共产生了除以m的余数remain. 不 ...
- BFS HDOJ 1242 Rescue
题目传送门 题意:从r走到a,遇到x多走一步,问最小走到a的步数 分析:因为r有多个,反过来想从a走到某个r的最小步数,简单的BFS.我对这题有特殊的感情,去年刚来集训队时肉鸽推荐了这题,当时什么都不 ...
- h5-22-地理位置
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- c语言读取一个文件夹下的全部文件(jpg / png 文件)
#include <cstdio> #include <cstring> #include <unistd.h> #include<dirent.h> ...
- 使用JS移除select的某些选项
var arrvalue = new Array("1", "3", "4", "5", "6", ...