对于值类型、引用类型来说比较过程样
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)用stingequals()方法故相等(多态)字符串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和p4p4=p3p3对对象引用赋给了p4p3和p4对同对象引用所两比较都返回true
MSDN概括了 Equals 方法和等号运算符 (==) 实现准则:
每次实现 Equals 方法时都实现 GetHashCode 方法使 Equals 和 GetHashCode 保持同步
每次实现相等运算符 (==) 时都重写 Equals 方法使们执行同样操作样使用 Equals 方法基础结构代码( Hashtable 和 ArrayList)行与用相等运算符编写用户代码相同
每次重写 Equals 方法时都实现相等运算符 (==)
引用类型实现相等运算符 (==)
大多数语言确实引用类型提供默认相等运算符 (==) 实现因此引用类型实现相等运算符 (==) 时应小心大多数引用类型(即使实现 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方法