对于值类型、引用类型来说比较过程
样![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
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
因
值类型
存储
内存![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
堆栈(![](https://i-blog.csdnimg.cn/blog_migrate/74c6f4ca42aa04675a88ae1cbad055d9.png)
简称栈)
而引用类型
变量
栈
仅仅
存储引用类型变量
地址
而其本身则存储
堆![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
一般来说:
"==" : 操作, 对于值类型,比较![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
两
变量
值
否相等;对于引用型变量表示![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
两
变量
堆
存储
地址
否相同
即栈![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
内容
否相同
"equals" : 操作表示
两
变量是否是对同![](https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png)
对象
引用
即堆![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
内容
否相同
而字符串![](https://i-blog.csdnimg.cn/blog_migrate/d9716f8e1a4db9f4862f9efaf0248d5b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png)
特殊
引用型类型![](https://i-blog.csdnimg.cn/blog_migrate/86df388af00f5709d701a4ba4711f02c.png)
C#语言![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
重载了string 对象![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
多方法方法(包括equals()方法)
使string对象用起来
像
值类型
样
因此
上面
例子![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
第
对输出 ,字符串a和字符串b
两
比较
相等![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
对于 第二对输出 object g = a 和object h = b ,
内存
两![](https://i-blog.csdnimg.cn/blog_migrate/9ae775c5ffe95e660ce75bc7318ffbfd.png)
同
对象
所![](https://i-blog.csdnimg.cn/blog_migrate/74c6f4ca42aa04675a88ae1cbad055d9.png)
栈![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
内容![](https://i-blog.csdnimg.cn/blog_migrate/d9716f8e1a4db9f4862f9efaf0248d5b.png)
相同![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
故
相等
而g.equals(h)用![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
sting
equals()方法故相等(多态)![](https://i-blog.csdnimg.cn/blog_migrate/6bdaae6b66306bed5923b3f0c5f68701.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fa32fae30e2e259c84575e28ff4b1ff7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0d4f79b15b31f1cce4ac5a14ca98cb16.png)
字符串a和b作
样
修改:
string a="aa";
string b="aa";
则
g和h
两
比较都
相等![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6bdaae6b66306bed5923b3f0c5f68701.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f10bf563b90471f9d6a5f767a8f4088a.png)
因
系统并没有给字符串b分配内存
只![](https://i-blog.csdnimg.cn/blog_migrate/d9716f8e1a4db9f4862f9efaf0248d5b.png)
"aa"指向了b
所
a和b指向![](https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png)
同![](https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png)
字符串(字符串![](https://i-blog.csdnimg.cn/blog_migrate/51c4bbb33ce6e7ee3a9edce48a7f1d66.png)
种赋值
情况下做了内存
优化)
对于p1和p2
也
内存
两![](https://i-blog.csdnimg.cn/blog_migrate/9ae775c5ffe95e660ce75bc7318ffbfd.png)
同
对象
所![](https://i-blog.csdnimg.cn/blog_migrate/74c6f4ca42aa04675a88ae1cbad055d9.png)
内存![](https://i-blog.csdnimg.cn/blog_migrate/ec70e9f6ee4e197b84dbee3ff44f7114.png)
地址肯定
相同
故p1==p2会返回false
又因
p1和p2又
对
同对象
引用
所
p1.equals(p2)
返回false
对于p3和p4
p4=p3
p3
对对象
引用赋给了p4
p3和p4
对同![](https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png)
对象
引用
所
两
比较都返回true
MSDN
概括了 Equals 方法和等号运算符 (==)
实现准则:
每次实现 Equals 方法时都实现 GetHashCode 方法![](https://i-blog.csdnimg.cn/blog_migrate/6bdaae6b66306bed5923b3f0c5f68701.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f10bf563b90471f9d6a5f767a8f4088a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a1edf80a9a88be7da7ddcdd4cfaf8659.png)
使 Equals 和 GetHashCode 保持同步
每次实现相等运算符 (==) 时
都重写 Equals 方法
使
们执行同样
操作![](https://i-blog.csdnimg.cn/blog_migrate/6bdaae6b66306bed5923b3f0c5f68701.png)
样
使用 Equals 方法
基础结构代码(
Hashtable 和 ArrayList)
行![](https://i-blog.csdnimg.cn/blog_migrate/18857acec2fd4265997dbbe31b9a9252.png)
与用相等运算符编写
用户代码相同
每次重写 Equals 方法时都实现相等运算符 (==)
引用类型
实现相等运算符 (==)
大多数语言确实
引用类型提供默认
相等运算符 (==) 实现
因此![](https://i-blog.csdnimg.cn/blog_migrate/86df388af00f5709d701a4ba4711f02c.png)
引用类型
实现相等运算符 (==) 时应小心
大多数引用类型(即使
实现 Equals 方法
引用类型)都
应重写相等运算符 (==)
好了
下面
考题
相信答案大家都知道了
Console.WriteLine((2 + 2) == 4); //True, 值类型,值相等
object s = 1;
object t = 1;
Console.WriteLine(s == t); //False
Console.WriteLine(s.Equals(t)); //True, 值类型封装的依旧比较值;
string a = "hello";
string b = String.Copy(a);
string c = "hello";
Console.WriteLine(a == b); //True, 记住,String当做值类型比较, 因为针对String类的特殊处理
Console.WriteLine(Object.Equals(a, b)); //True, 同上
Console.WriteLine((object)a == (object)b); //False, 引用的是不同对象
Console.WriteLine(Object.Equals((object)a, (object)b)); //True, 多态,调用String的Equals方法
Console.WriteLine((object)a == (object)c); //True, 字符串的内存优化,两个"Hello"指向同一内存空间
Console.WriteLine(Object.Equals((object)a, (object)c)); //True, 多态,调用String的Equals方法