但是在比较字符串的时候是有差别的!其他时候一样.string a = "111";
string b = "111";if(a == b)
{
    //输出标记
}if(a.Equal(b))
{
   //输出
}if((object)a ==(object)b)
{
  //输出标记
}在字符串比较的时候是有差别的.

解决方案 »

  1.   

    Equals方法的目的是比较两个类型实例是否相等,如果两个实例有相同的状态和值,我们将使其返回为true==默认比较两个引用是否相等(前提是==操作符两边的变量都是System.Object类型)
      

  2.   

    equals方法是Object类的一个方法,
    所有继承自Object类的类都会集成此方法,并且可以重载这个方法来实现各自的比较操作,
    所以开发人员尽可以在自己的类中实现自己的equals方法来完成自己特定的比较功能,所以各个类的equals方法与= =之间并没有绝对的关系,
    这要根据各自类中自己的实现情况来看。
    也就是说可能会有两种情况发生:
    equals方法和= =相同或者不相同。在多数情况下这两者的区别就是究竟是对对象的引用进行比较还是对对象的值进行比较(其他特殊情况此处不予考虑)。
    那么= =操作符是比较的什么呢?= =操作符是比较的对象的引用而不是对象的值。http://java.ccidnet.com/art/3737/20041114/473237_1.html
    虽是JAVA,但说的是同一个道理
      

  3.   

    在比较字符串的时候和java是不一样的,c# prime plus上专门提到过.
      

  4.   

    ==是比较值是否相同
    而equal是比较是否为同一对象似乎
      

  5.   

    ==对于内置值类型,判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false.
    而对于用户定义的值类型,如果没有重载==操作符,==将是不能够使用的。例如:struct
    默认对于引用类型,用于比较两个引用类型的对象是否是对于同一个对象的引用
    Equals方法对于值类型和引用类型的定义不同,对于值类型,类型相同,并且数值相同(对于struct的每个成员都必须相同),则Equals返回true,否则返回false;
    默认对于引用类型,用于比较两个引用类型的对象是否是对于同一个对象的引用
      

  6.   

    这个不能一概而论,如果这样说可能还可以,object的Equals()方法和object的==操作符有什么区别,那还有的一说。
      

  7.   

    大多数情况下Equals是比较值是否相等的,而==是比较是不是同一个对象的引用有些时候==被重载了,例如string的
      

  8.   

    Equals是从Object继承而来的,默认的Object.Equals实现是对引用进行比较,因此如果继承类不对该方法进行重写,则就是默认的对引用进行比较。==是运算符,你必须手动对你自己的类型实现“==”,如果你的实现是对引用(Equals为默认实现时)进行比较,则这两个就是一样的,如果不是,那么在Equals为默认实现时,这两个就是不同的。
      

  9.   

    Equals是从Object继承而来的,默认的Object.Equals实现是对引用进行比较,因此如果继承类不对该方法进行重写,则就是默认的对引用进行比较。==是运算符,你必须手动对你自己的类型实现“==”,如果你的实现是对引用(Equals为默认实现时)进行比较,则这两个就是一样的,如果不是,那么在Equals为默认实现时,这两个就是不同的。==================================================================================这个是对的,我现在才知道我误解了很久啊,当时学java的时候书上就是说equals是比较值,而==是引用比较,现在才知道误解好多年啊....更加明白一点庸师害死人!我想java默认equals也是比较引用的,只是jdk里那些对象都重载了Equals而已~~~~PS:鄙视下不懂乱写书的!
      

  10.   

    ==是比较值是否相同
    而equal是比较是否为同一对象
      

  11.   

    楼上理解错误~~~~
    试试下面代码,你会明白!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();
            }
        }
    }
      

  12.   

    有兴趣的同学试一下这段代码:
        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
      

  13.   

    从上面的例子可以看出,当==用于字符串对象时,有时是比较值相等,有时是比较引用相等。我能想到的相等的概念只有两种,引用相等和值相等。由于C#已经有Object.ReferenceEquals()来判断引用相等,允许程序员对Equals, ==, != 重载不同的实现会导致概念的混淆。如果能禁止==和!=的重载,并使用Equals用于值相等的判断会更清楚一些。操作符==应该由编译器解释为ReferenceEquals或者Equals。同样操作符!=应该由编译器解释为!(a==b)。可能有人会争辩C#这样设计是有目的的。比如Equals用于Hashtable/Dictionary的对象相等判定而设计,操作符==,<,>,>=,<=用于序关系描述。然而,当重载操作符<时,编译器只要求也重载操作符>而并不要求重载==。是不是很奇怪?
      

  14.   

    To wangjun8868,
    我同意我们可以理解为一个是字符串,一个是对象。
    我觉得诡异是因为,从代码中看,a==b, b==c, 但是a!=c。操作符==没有传递性?我们什么时候需要用到这样的无传递性的==?
      

  15.   

    http://www.cnblogs.com/wennxxin/archive/2008/10/08/1306392.html
    我的博客里面做了详细的介绍
      

  16.   

    帅哥wennxxin,
    你的博客不能解释我例子中的a==b,b==c,但是a!=c的情况。
    而且对内置引用类型string,==并不是比较引用。
      

  17.   

    呵呵,对不起,是不能解释a==b,a==c, 但是b!=c的情况。
      

  18.   

    ==是值比较,equal是对象比较。。即使对象的值相等如果其他的不同那也是为假。
      

  19.   

    c#支持符号重载,因此对于==符号,实际上也是有可能重载的。例如string类型就对符号两边都是string类型对象的操作进行了重载,编程直接返回Equals的结果,而不是原来的未经重载的==结果。因此,==未必是==,Equals未必是Equals,它的结果可以鱼目混珠,关键是你不要用初始的概念去套用具体化的概念,要知道历史上的事情(呵呵,只能这样说了)。
      

  20.   

    所以说“equals是比较值,而==是引用比较”也是对的,对于引用类型而言天生的“==”就是比较地址。只是理解这句话的人只是死板地把这句话当作教条,没有想到操作符会被重载的。只要进一步想想教条是可以被重载的就可以了。
      

  21.   

    其实,我们可以把某个自定义类型Equals重写为比较地址(当然我这里指浮动地址例如HashCode),把==重载为比较值,哈哈,使用者更加会摸不着头脑。但是明白了我说的这两句话,业务无所谓教条了,会去实际去高清一个类型它到底比较什么,在进行实际发现行动之前事先并没有可能根据猜测名称就给出定论。
      

  22.   

    ==,比较的是栈内的内容,就是值类型的比较或者对引用的比较。值类型用“==”比较,就是比较的值,引用类型比较则是比较这两个引用类型的存在栈内的地址是否相同。
    Equals()分为虚拟方法和静态方法两种,比较的是引用,同ReferenceEquals(),但是Equals()的虚拟方法常常被override,以比较引用类型实际的值,这是它最重要的用途,比如.Net的string类就重写了Equals()方法,用于比较两个字符串的值是否相等,而不是引用是否相等。如果值类型用Equals()方法比较的话,结果一定返回为false,因为必须先进行装箱操作。
      

  23.   


    这个说法貌似不正确。Equals()比较的也是引用,string的Equals()之所以比较的具体的值,是因为.net已经把它重写了
      

  24.   

    对于string来说,它仅仅重载了==的两边都是string的情况。当两边不都是string类型,还是使用原来的未经重载的==运算的。从结果上看,就可以看到两个==含义。
      

  25.   

    To sp1234,
    我的问题不是要理解==的行为,而是探讨C#作成这个样子倒底是为什么?只是为了本不需要的可重载性而导致二义性,还是有其他深意。至今在本贴我还是只看到了两个判断相等的需求,没有看到第三个。为什么我们需要三个不同的(或可能会不同的)“相等判定”的实现(ReferenceEquals, Equals & ==)?
      

  26.   

    如果大家对我的观点还有不同意见,请在给意见的同时给一个实际的例子,来说明在什么需求下,我们需要对一个类型的对象有不同的Equals和==的实现,并且这两个实现和ReferenceEquals都不相同。
      

  27.   


    因为任何事情都坑内有例外。c#发现个人理想做法有时候要根据人们的愿望做一点改变,他发现原来c#还要满足vb之类的开发者的习惯写法,尽管这种调整看起来很丑陋。
      

  28.   

    话也要说开来,其实上面咱们虽然在讨论c#,但是这其实.net的机制,而不是c#独特的。.net是一个跨语言的平台,当然要考虑到各种语言的程序员。
      

  29.   

    :)同意sp1234 .net需要支持各种语言而不只是C#. 考虑到C++,VB等语言的习惯写法,的确应该做一些调整。其实MS也发现了这个问题,并且对这个问题有一个规范。参见中文版:http://msdn.microsoft.com/zh-cn/library/ms173147.aspx(英文版:http://msdn.microsoft.com/en-us/library/ms173147.aspx)。规范中对ReferenceEquals,Equals和操作符==作了如下描述 (部分摘录)
    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类库实现者)的混淆。