但是在比较字符串的时候是有差别的!其他时候一样.string a = "111";
string b = "111";if(a == b)
{
//输出标记
}if(a.Equal(b))
{
//输出
}if((object)a ==(object)b)
{
//输出标记
}在字符串比较的时候是有差别的.
string b = "111";if(a == b)
{
//输出标记
}if(a.Equal(b))
{
//输出
}if((object)a ==(object)b)
{
//输出标记
}在字符串比较的时候是有差别的.
所有继承自Object类的类都会集成此方法,并且可以重载这个方法来实现各自的比较操作,
所以开发人员尽可以在自己的类中实现自己的equals方法来完成自己特定的比较功能,所以各个类的equals方法与= =之间并没有绝对的关系,
这要根据各自类中自己的实现情况来看。
也就是说可能会有两种情况发生:
equals方法和= =相同或者不相同。在多数情况下这两者的区别就是究竟是对对象的引用进行比较还是对对象的值进行比较(其他特殊情况此处不予考虑)。
那么= =操作符是比较的什么呢?= =操作符是比较的对象的引用而不是对象的值。http://java.ccidnet.com/art/3737/20041114/473237_1.html
虽是JAVA,但说的是同一个道理
而equal是比较是否为同一对象似乎
而对于用户定义的值类型,如果没有重载==操作符,==将是不能够使用的。例如:struct
默认对于引用类型,用于比较两个引用类型的对象是否是对于同一个对象的引用
Equals方法对于值类型和引用类型的定义不同,对于值类型,类型相同,并且数值相同(对于struct的每个成员都必须相同),则Equals返回true,否则返回false;
默认对于引用类型,用于比较两个引用类型的对象是否是对于同一个对象的引用
而equal是比较是否为同一对象
试试下面代码,你会明白!using System;
using System.Collections.Generic;
using System.Text;namespace testcode
{
class aaaa
{
private string test1; public string Test1
{
get { return test1; }
set { test1 = value; }
}
private string test2; public string Test2
{
get { return test2; }
set { test2 = value; }
}
}
}
-----------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;namespace testcode
{
class TestEquals
{
static void Main(string[] args)
{
aaaa a = new aaaa();
aaaa b = new aaaa();
a.Test1 = "1";
a.Test2 = "2";
b.Test1 = "1";
b.Test2 = "2";
if (a.Equals(b))
{
Console.WriteLine("a.equals(b)");
}
else
{
Console.WriteLine("!a.equals(b)");
}
if (a == b)
{
Console.WriteLine("a==b");
}
else
{
Console.WriteLine("a!=b");
}
Console.ReadLine();
}
}
}
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' });
object c = a;
Console.WriteLine(Object.ReferenceEquals(a, b));
Console.WriteLine(Object.ReferenceEquals(a, c));
Console.WriteLine(Object.ReferenceEquals(b, c));
Console.WriteLine(Object.Equals(a, b));
Console.WriteLine(Object.Equals(a, c));
Console.WriteLine(Object.Equals(b, c));
Console.WriteLine(a == b);
Console.WriteLine(a == c);
Console.WriteLine(b == c);
Console.WriteLine(a.Equals(b));
Console.WriteLine(a.Equals(c));
Console.WriteLine(b.Equals(c));
}
}结果很诡异。高手解释一下?或者是bug?结果:
False
True
False
True
True
True
True
True
False
True
True
True
我同意我们可以理解为一个是字符串,一个是对象。
我觉得诡异是因为,从代码中看,a==b, b==c, 但是a!=c。操作符==没有传递性?我们什么时候需要用到这样的无传递性的==?
我的博客里面做了详细的介绍
你的博客不能解释我例子中的a==b,b==c,但是a!=c的情况。
而且对内置引用类型string,==并不是比较引用。
Equals()分为虚拟方法和静态方法两种,比较的是引用,同ReferenceEquals(),但是Equals()的虚拟方法常常被override,以比较引用类型实际的值,这是它最重要的用途,比如.Net的string类就重写了Equals()方法,用于比较两个字符串的值是否相等,而不是引用是否相等。如果值类型用Equals()方法比较的话,结果一定返回为false,因为必须先进行装箱操作。
这个说法貌似不正确。Equals()比较的也是引用,string的Equals()之所以比较的具体的值,是因为.net已经把它重写了
我的问题不是要理解==的行为,而是探讨C#作成这个样子倒底是为什么?只是为了本不需要的可重载性而导致二义性,还是有其他深意。至今在本贴我还是只看到了两个判断相等的需求,没有看到第三个。为什么我们需要三个不同的(或可能会不同的)“相等判定”的实现(ReferenceEquals, Equals & ==)?
因为任何事情都坑内有例外。c#发现个人理想做法有时候要根据人们的愿望做一点改变,他发现原来c#还要满足vb之类的开发者的习惯写法,尽管这种调整看起来很丑陋。
C# 中有两种不同的相等:引用相等和值相等。值相等是大家普遍理解的意义上的相等:它意味着两个对象包含相同的值。例如,两个值为 2 的整数具有值相等性。引用相等意味着要比较的不是两个对象,而是两个对象引用,且两者引用的是同一个对象。(In C#, there are two different kinds of equality: reference equality (also known as identity) and value equality. Value equality is the generally understood meaning of equality: it means that two objects contain the same values. For example, two integers with the value of 2 have value equality. Reference equality means that there are not two objects to compare. Instead, there are two object references and both of them refer to the same object. )若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,请使用 Equals。(To check for reference equality, use ReferenceEquals. To check for value equality, you should generally use Equals. )
重写 Equals
由于 Equals 是一个虚方法,因此任何类都可以重写其实现。表示某个值(本质上可以是任何值类型)或一组值(如复数类)的任何类都应该重写 Equals。(Because Equals is a virtual method, any class can override its implementation. Any class that represents a value, essentially any value type, or a set of values as a group, such as a complex number class, should override Equals. )重写运算符 ==
默认情况下,运算符 == 通过判断两个引用是否指示同一对象来测试引用是否相等。因此引用类型不需要实现运算符 == 就能获得此功能。当类型不可变(即实例中包含的数据不可更改)时,通过重载运算符 == 来比较值是否相等而不是比较引用是否相等可能会很有用,因为作为不可变的对象,只要其值相同,就可以将其视为相同。建议不要在非不可变类型中重写运算符 ==。(By default, the operator == tests for reference equality by determining whether two references indicate the same object. Therefore, reference types do not have to implement operator == in order to gain this functionality. When a type is immutable, that is, the data that is contained in the instance cannot be changed, overloading operator == to compare value equality instead of reference equality can be useful because, as immutable objects, they can be considered the same as long as they have the same value. It is not a good idea to override operator == in non-immutable types.)System.String 类对象初始化后不能改变,是一个应用==规范的好的例子。但是并非.NET 类库都遵守这个规范。举个例子:在System.Drawing.Point中(类似的还有Point, Rectangle, etc), Point 不是一个不可变类型(Point.Offset会改变已初始化的Point对象的状态), 但该类却重载了==并用于值比较。当然我同意Point的实现者是为了符合之前C++中的编程习惯,但毕竟和规范不符。作为本篇的小结:
- MS对ReferenceEquals和Equals有明确的规范 (橙色引用文字)。未发现和规范不一致的.net类库。
- 对于操作符==,从规范中看出,态度比较暧昧。一方面MS希望接近于Java的==的规范而倾向于引用相等(见上一段蓝色字段。也许是因为.net语言的主设计师曾经是Java的主设计师,也可能是为了照顾J#用户);另一方面为了兼容C++的==重载习惯,对一些值类型依然希望使用操作符==作为值相等的操作符。(上一段的红色字段)从而导致了大家使用时(包括.net类库实现者)的混淆。