9

请看下面的代码:

using System;
class MyClass
{
    static void Main()
    {
        object o = ".NET Framework";
        object o1 = new string(".NET Framework".ToCharArray());
        Console.WriteLine(o == o1);
        Console.WriteLine(o.Equals(o1));
    }
}

结果是:


现在考虑这个:

using System;
class MyClass
{
    static void Main()
    {
        object o = ".NET Framework";
        object o1 = ".NET Framework";
        Console.WriteLine(o == o1);
        Console.WriteLine(o.Equals(o1));
    }
}

结果是 :
真真

“==”比较对象引用是否相同,而“.Equals()”比较内容是否相同。我想知道这些代码有什么不同?!

object o1 = new string(".NET Framework".ToCharArray());

object o1 = ".NET Framework"; 

他们都变成了一个对象,但为什么结果不同?

4

3 回答 3

15

他们都变成了一个对象,但为什么结果不同?

在第二种情况下,您对oando1赋值使用相同的字符串常量。C# 保证同一程序中的任何两个相等的字符串常量表达式都将引用同一个字符串对象。所以 和 的值oo1相同的参考。

虽然我找不到更通用的形式(对于常量字符串表达式),但 C# 规范的第 2.4.4 节实际上涵盖了您的情况:

当根据字符串相等运算符等效的两个或多个字符串文字出现在同一程序中时,这些字符串文字引用相同的字符串实例。

编辑:关于以下行为的快速说明==

  • 如果两个操作数的编译时类型为==,将使用 提供的重载string,这将执行内容比较
  • 否则,如您在问题中所述,将使用仅比较引用是否相等的“默认”实现。

在您的情况下,操作数的编译时类型都是 both object,因此它真正使用引用相等。

于 2013-05-03T09:44:53.233 回答
3

也许您感到困惑,因为 use 使用的是类型object而不是string.

如果object通过 operator 比较两个 s ==,则仅比较对这些对象的引用。由于同一程序集中的两个常量字符串合并为一个,因此它们具有相同的引用。

如果您string通过操作比较两个 s,==则使用另一种方法。字符串有一个运算符覆盖==. 请参阅:http: //msdn.microsoft.com/en-us/library/system.string.op_equality (v=vs.110).aspx 。此覆盖不比较引用,它比较两个对象的值。在您的示例中,编译器现在不能两种类型都是类型,string因为您正在使用objects. 这就是为什么string operation ==不用于比较o和的原因o1

回到Equals函数。Equals是一个可以通过继承类来覆盖的函数。在这种情况下,string该类已覆盖它并用他自己的比较方法替换它。whereobject.Equals只比较引用,string.Equals比较值。

编辑

所以......这将产生你的“奇怪”价值观:

    object o = ".NET Framework";
    object o1 = new string(".NET Framework".ToCharArray());
    Console.WriteLine(o == o1); // Will prodcuce: False.
    Console.WriteLine(o.Equals(o1)); // Will prodcuce: True.

这将产生预期值:

    string o = ".NET Framework";
    string o1 = new string(".NET Framework".ToCharArray());
    Console.WriteLine(o == o1); // Will prodcuce: True.
    Console.WriteLine(o.Equals(o1)); // Will prodcuce: True.
于 2013-05-03T09:58:41.357 回答
2

您的第二个示例使用来自实习生池的字符串,这就是为什么它们的引用也相等,而在您的第一个代码示例中,您有两个不同的字符串对象。考虑以下示例。

object o = ".NET Framework";
object o1 = ".NET Framework";
object o2 = new string(".NET Framework".ToCharArray());
Console.WriteLine(o == o1);
Console.WriteLine(o.Equals(o1));
Console.WriteLine(Object.ReferenceEquals(o,o1)); //True
Console.WriteLine(Object.ReferenceEquals(o, o2)); //False

编辑:

从其他帖子的评论中,我想我应该提到,==相对于的当前行为string与其他引用类型不同:

== 运算符(C# 参考)- MSDN

对于字符串以外的引用类型,== 如果它的两个操作数引用同一个对象,则返回 true。对于字符串类型,== 比较字符串的值。

所以以下将导致true

string o = ".NET Framework";
string o2 = new string(".NET Framework".ToCharArray());
Console.WriteLine(o == o1); //True

因为现在类型是string,不是object

于 2013-05-03T09:45:39.927 回答