“stringDemo”与新字符串(“stringDemo”.ToCharArray);

时间:2013-05-03 09:42:36

标签: c# .net oop c#-4.0

请查看以下代码:

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"; 

他们两个都是一个对象,但为什么结果不同?

3 个答案:

答案 0 :(得分:15)

  

他们两个都是一个对象,但为什么结果不同?

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

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

  

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

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

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

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

答案 1 :(得分:3)

也许您感到困惑,因为使用object类型代替string

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

如果您通过操作string比较两个==,则使用另一种方法。 String具有==的运算符覆盖。见:http://msdn.microsoft.com/en-us/library/system.string.op_equality(v=vs.110).aspx。此覆盖不比较引用,它比较两个对象的值。在您的示例中,编译器现在不能同时使用string类型,因为您使用的是objects。这就是string operation ==未用于比较oo1的原因。

返回Equals功能。 Equals是一个可以通过继承类来覆盖的函数。在这种情况下,string类已覆盖它并用他自己的比较方法替换它。 object.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.

答案 2 :(得分:2)

您的第二个示例使用来自intern pool的字符串,这就是他们的引用相同的原因,而在您的第一个代码示例中,您有两个不同的字符串对象。请考虑以下示例。

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相关的当前行为与其他参考类型不同:

== Operator (C# Reference)- MSDN

  

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

因此,以下内容将导致true

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

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