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 true false false false true true
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 true false false false true true
Equals 的默认实现仅支持引用相等,但派生类可重写此方法以支持值相等。
默认情况下,运算符 == 通过判断两个引用是否指示同一对象来测试引用是否相等,
因此引用类型不需要实现运算符 == 就能获得此功能。当类型不可变时,
意味着实例中包含的数据不可更改,此时通过重载运算符 == 来比较值是
否相等而不是比较引用是否相等可能会很有用,因为作为不可变的对象,
只要它们具有相同的值,就可以将它们看作是相同的。建议不要在非不可变类型中重写运算符 ==。 若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,应使用 == 或 Equals。
==: 确定两个同类型的值是否相等!
== 是判断值是否相同
equals 是判断地址是否相同
而string类型对象的==和equals 都是比较值,这是比较特殊的
"==" : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
"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。
equals 用于确定两个 Object 实例是否相等。
== 用于确定两个同类型的值是否相等!然而,事实上,在.net以后的版本中,如果两个对象可以 ==,那么它们一定是 equals 的!
在现在的.net中,equals 于 == 已经完全没有区别!不信大家可以去做个试验,
创建两个不同的对象,让它们的值相等,看它们是否 equals !
下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则: 每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。每次实现 IComparable 时都要重写 Equals 方法。实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 (<) 和大于 (>) 运算符的运算符重载。不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。有关 Equals 方法的相关信息,请参见实现 Equals 方法。在值类型中实现相等运算符 (==)
大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。每次重写 Equals 方法时都实现相等运算符 (==)。在引用类型中实现相等运算符 (==)
大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。
"equals()" 判断两个object是否 “一样” (所有成员值一样...)
例如:
1)
string a = "abc";
string b = "abc";
a==b //true;
a.equals(b) //true;
----------
2)
string a = new string("abc");
string b = new string("abc");
a==b // false!!!!!!!!
a.equals(b) //true 在例1中, “abc"是放在常量池(constant pool)里头的,所以,虽然a,b都“=”“abc”
但是内存中只有一份copy,所以“==”返回true
但是例2中,new方法决定了 两个不同的string “abc”被创建放在了内存heap区,分别被a和b所指向,因此,“==”返回了false!
对于对象实体
如
string str1 = new string("hello,world!");
string str2 = new string("hello,world!"); hashmap hm1 = new hashmap();
hashmap hm2 = new hashmap();
可以用==也可以用equals(),意义不一样
因为每个对象实体使用reference引用,==实际去比较reference的地址 equals()是基类object定义的一个方法,用于同一类型之间的比较,你可以override,
自己定义比较两个对象的规则。 string的equals方法里定义的规则是字符串相同,equals()就返回true
所以以上str1==str2返回false(因为显然他们地址不一样)
str1.equals(str2)返回true,因为它们的字符串内容相同
对于值类型来说: ==比较的是值还是引用对象地址 equals是值还是引用对象地址
对于引用对象来说:==比较的是值还是引用对象地址 equals是值还是引用对象地址
UP!!!!!
我还想说的是字符串驻留的东西!这个东西可以让== 的结果产生变化! 下面是以前我写的一点东西!
在声明一个String类型的变量时调用的IL指令是ldstr(LoadString),而声明其它的引用类型则IL指令为:newobj
在.net framework中有一个字符串驻留池,存在一个类似HashTable的东西,以Key,value的形式存储我们所声明的大部分String 变量(有部分特殊的),
例1:
string a = "string1";
string b = "string"+"1";
object.ReferenceEquels(a,b) -->结果是True
结果有点让人意外,为什么这两个对象是同一对象????原因就是字符串驻留机制,
声明 a 的时候会分配一块内存, 在声明b的时候,由于b的value是 直接赋值,所以会默认的启用驻留,去驻留池中的hashtable查找是否有一个相同的key,如果有,
a 和 b就共享同一块内存, 如果没有找到,则重新分配一块内存,
例2: string a = "string1";
string d = "1";
string e = "string";
string f = e + d;
object.ReferenceEquals(a , f) --->结果是false
其实a 和f 的值 是一样的, 如果用上面的解释来说,这里就应该是true , 但是这里确是 false ,他们不是同一对象,
因为f 是动态的赋值,那么 在声明f 的时候它的值就没有确定下来(上面的是直接赋值), 所以CLR就不会对它启用驻留机制,
为了让它启用驻留机制可以使用: 1) string f =string.Intern(e + d); 2)object.ReferenceEquals(a ,string.Intern(f))
string.Intern是强制启用在字符串驻留,这样它就会去驻留池中查找,这样是不是节省了内存了????
object.ReferenceEquals(a ,string.Intern(f)) -->结果是True
网上资料:http://tech.it168.com/d/2008-05-20/200805200826862.shtml
equals是比较对象的内容,它是个方法,继承自Object类,可以被用户覆盖.
==是个关系运算符,当被比较者是基本类型时,比较其值是否相等;
当被比较者是引用类型时,比较其是否引用同一个对象(或者说比较其是否指向同一个内存地址)
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);以上引自 MSDN, 谁能给个正确结果
object g = a;
object h = b;
Console.WriteLine(g == h);
Console.WriteLine(g.Equals(h)); false true如何获得的结果
object g = a; //应该为"a"
object h = b; //应该为"b" Console.WriteLine(g == h); //结果应该为false
Console.WriteLine(g.Equals(h)); //结果应该为false false true //错误结果
若:
g="a";h="a";
Console.WriteLine(g == h); //结果应该为true
Console.WriteLine(g.Equals(h)); //结果应该为true
如何获得的结果//至于如何获取结果,请对这个Console.WriteLine()方法进行理解一下…
Console.WriteLine((2 + 2) == 4);// True
object s = 1;
object t = 1;
Console.WriteLine(s == t);//False string a = "hello";
string b = String.Copy(a);
string c = "hello"; Console.WriteLine(a == b);//True
Console.WriteLine(a.Equals(b));//True Console.WriteLine((object)a == (object)b);//False
Console.WriteLine((object)a.Equals((object)b));//True
Console.WriteLine((object)a == (object)c);//True
Console.WriteLine((object)a.Equals((object)c));//True Console.WriteLine((object)b == (object)c);//False
Console.WriteLine((object)b.Equals((object)c));//True
http://www.tracefact.net/CSharp-Programming/Type-Fundamentals.aspx
a:对于预定义的值类型,如果操作数的值相等,则相等运算符返回true,否则返回false。
b:对于string以外的引用类型,如果两个操作数引用同一个对象,则返回true。
c:对于string引用类型,比较字符串的值。2 equals()
比较引用类型是否对同一对象的引用,内容相同的不同实例返回false。
对于sting引用类型,比较其值是否相同。
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); //true --对于string引用类型,比较字符串的值。值相等则返回true
Console.WriteLine(a.Equals(b)); //true --对于string引用类型,比较字符串的值。值相等则返回true
object g = a;
object h = b;
Console.WriteLine(g == h); //false --对于其它引用类型,比较引用是否同一对象,不是同一对象的引用 ,返回false
Console.WriteLine(g.Equals(h)); //false --对于其它引用类型,比较引用是否同一对象,不是同一对象的引用 ,返回false Person p1 = new Person("jia");
Person p2 = new Person("jia");
Console.WriteLine(p1 == p2); //false --对于其它引用类型,比较引用是否同一对象,不是同一对象的引用 ,返回false
Console.WriteLine(p1.Equals(p2)); //false --对于其它引用类型,比较引用是否同一对象,不是同一对象的引用 ,返回false
Person p3 = new Person("jia");
Person p4 = p3;
Console.WriteLine(p3 == p4); //true --对于字符串以外的引用类型,比较是否同一对象的引用,是,返回true
Console.WriteLine(p3.Equals(p4)); //true --对于字符串以外的引用类型,比较是否同一对象的引用,是,返回true Console.ReadLine();
}
} 所以结果是:true true false false false false true true
effective c# 其中有一节就是讲的几个相等判断,在csdn就有阅读
true true false true false false true true---~~~~
对于引用类型,== 默认的行为与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 trueequals returns true 注:对于String类,直接声明s1 = “the test a”的话,输出结果将包含"ReferenceEquals returns true",因为默认的,String对于声明的相同的字符串在堆上只保留一个Copy,所以s1与s2将会指向相同的Reference,
比较两个对象(object),用equal
同意这个朋友所说,msdn的帮助太官方了。================================================================================
viewerwang's life
http://lelespace.com/
================================================================================
a:对于预定义的值类型,如果操作数的值相等,则相等运算符返回true,否则返回false。
b:对于string以外的引用类型,如果两个操作数引用同一个对象,则返回true。
c:对于string引用类型,比较字符串的值。 2 equals()
比较引用类型是否对同一对象的引用,内容相同的不同实例返回false。
对于sting引用类型,比较其值是否相同。
比较object类型
但是从核心上来说,==是否同一引用,equals是值相等...由于你所定议的类都是Object的子类,那么==和equals是一样的...
我想问一下 equals() 对于预定义的值类型也是"如果操作数的值相等,则相等运算符返回true,否则返回false"吗?更正一下答案 true true false true false false true true我还是不明白第三、第四个答案是怎么获得的?
a:对于预定义的值类型,如果操作数的值相等,则相等运算符返回true,否则返回false。
b:对于string以外的引用类型,如果两个操作数引用同一个对象,则返回true。
c:对于string引用类型,比较字符串的值。 2 equals()
比较引用类型是否对同一对象的引用,内容相同的不同实例返回false。
对于sting引用类型,比较其值是否相同。
“==”是同一的关系,也就是实际上是判断内存地址是不是一样的
“equals”是判断值是不是相等的,内存地址则涉及不到
而equals 是字符型的
== 是比较值
Equals 是比较地址初学 初学