Object ==等式失败,但.Equals成功。这有意义吗?

时间:2012-10-08 04:22:03

标签: c# .net

  

可能重复:
  Difference between == operator and Equals() method in C#?

两种形式的平等,第一种失败,第二次成功。

(object)"abc" == (object)"abc"
false

((object)"abc").Equals((object)"abc")
true

在下面的参考文献中,我们看到“C#中的等式运算符不是多态的”

参考:String Equality operator == in c#

顺便说一下:还不确定为什么这是一个问题。我认为它可能是这样的,但不是因为这个测试成功了。

    static void Main(string[] args) {
        var o = new classOfT<string>() { val = "abc" };
        Console.WriteLine((object)o.val == "abc");
    }

    public class classOfT<T> {
        public string val { get; set; }
    }
顺便说一句:我不同意这个问题的完全重复规则,但是嘿。

答案说明:

  

... String类包含静态bool Equals(字符串a,   string b)方法和静态bool Equals(对象a,对象b)方法。   不同之处在于前者是在String类中定义的   本身,而后者继承自Object类(即   String的基类

语义上这是有道理的,但它在OO和C#语言的更广泛的上下文中是否有意义?

为什么我要为这个问题烦恼?好吧,刚刚发现了一个错误,我想以韵律或理由而不是在“只记得这个”的情况下在我的大脑中存档,它会在类别之前咬你。

更新

目前正在考虑使用原语(从功能角度来看)Vs多态性。因为我一直在做越来越多的功能性的东西,这可能是为什么母语让我感到困惑。我还没有想到这一点(不,我不是务实。我被语言设计所吸引)。感谢您的回复!

4 个答案:

答案 0 :(得分:3)

(object)"abc" 

将从字符串对象创建一个Object引用。这样做

(object)"abc" == (object)"abc"

将创建两个不相等的对象引用。

但是,使用equals方法将检查存储的字符串的值是否相等。同样,这不是所有对象的默认实现,而是String对象的默认实现。对于任何自定义对象,您应该定义自己的equals方法的自定义实现来实现此行为。

答案 1 :(得分:2)

代码示例返回true。

(object)"abc" == (object)"abc"

我认为您提供了与应用程序中返回false的代码不同的示例。 CLR使用字符串实习进行字符串优化。转换为System.Object将导致==运算符比较引用,并且由于字符串实习功能,==运算符将导致为true。如果==运算符两边的参数将引用堆上的不同字符串对象,则比较将仅返回false。

检查程序集是否已标记[assembly: CompilationRelaxations(System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterning)]属性。

答案 2 :(得分:1)

字符串比较应通过String.Compare

完成

http://blogs.msdn.com/b/abhinaba/archive/2005/10/28/486173.aspx

http://msdn.microsoft.com/en-US/vstudio/aa496123?pull=/library/en-us/dndotnet/html/StringsinNET20.asp

我不认为你“发现了一个bug”,因为微软在.NET BCL中做了很多次,而且我们作为开发人员必须适应这种情况。一个简单的例子就是,

var ip1 = IPAddress.Parse("127.0.0.1");
var ip2 = IPAddress.Parse("127.0.0.1");

您会找到ip1 != ip2,但ip1.Equals(ip2) == true。建议的比较方法是IPAddress.Compare(ip1, ip2)。无论如何,你有时必须记住一些事情。

答案 3 :(得分:0)

== operator

  

对于预定义的值类型,等于运算符(==)返回true,如果   其操作数的值相等,否则为false。以供参考   除了string之外的类型,==如果它的两个操作数引用则返回true   同一个对象。对于字符串类型,==比较的值   字符串。

Equals

  

由字符串类覆盖,如果obj是a,则返回true   字符串及其值与此实例相同;否则,是的。“

如果您的代码如下所示,

var s1= GetString1(); //some string object
var s2= GetString2(); //some string object containing same content as s1

(object)s1 == (object)s2
returns false - because == compares the references of the objects (which will be different if not interned)

((object)s1).Equals((object)s2)
returns true - because Equals will be called between actual strings at run time

但是,在当前表单中,您的代码

(object)"abc" == (object)"abc"
((object)"abc").Equals((object)"abc")

应该在两种情况下都返回true,因为具有相同值的文字字符串默认情况下被中断,因此引用相同的对象(即引用也相等)