我最近接触了一个大型代码库,并注意到所有字符串比较都使用string . equals()而不是==

你认为这是什么原因?


当前回答

==和String之间有一个微妙但非常重要的区别。=方法:

class Program
{
    static void Main(string[] args)
    {
        CheckEquality("a", "a");
        Console.WriteLine("----------");
        CheckEquality("a", "ba".Substring(1));
    }

    static void CheckEquality<T>(T value1, T value2) where T : class
    {
        Console.WriteLine("value1: {0}", value1);
        Console.WriteLine("value2: {0}", value2);

        Console.WriteLine("value1 == value2:      {0}", value1 == value2);
        Console.WriteLine("value1.Equals(value2): {0}", value1.Equals(value2));

        if (typeof(T).IsEquivalentTo(typeof(string)))
        {
            string string1 = (string)(object)value1;
            string string2 = (string)(object)value2;
            Console.WriteLine("string1 == string2:    {0}", string1 == string2);
        }
    }
}

产生如下输出:

value1: value2: value1 == value2: True value1.Equals (value2):真的 string1 == string2: True ---------- value1: value2: value1 == value2: False value1.Equals (value2):真的 string1 == string2: True

可以看到==运算符对两个明显相等的字符串返回false。为什么?因为泛型方法中使用的==运算符被解析为System定义的op_equal方法。对象(该方法在编译时拥有的T的唯一保证),这意味着它是引用相等而不是值相等。

当有两个值类型为System时。String,则==具有值相等语义,因为编译器将==解析为System.String。op_equal代替System.Object.op_equal。

所以为了安全起见,我几乎总是使用String。我总是得到我想要的值相等语义。

如果其中一个值为null,为了避免nullreferenceexception,我总是使用静态String。=方法:

bool true = String.Equals("a", "ba".Substring(1));

其他回答

这篇文章有一篇文章,你可能会觉得很有趣,引用了乔恩·斯基特的话。看起来用途是差不多的。

Jon Skeet指出,实例Equals的性能“在字符串较短时略好——随着字符串长度的增加,这种差异变得完全不重要。”

这两种方法在功能上是相同的——它们比较值。 正如MSDN上写的那样:

关于字符串。Equals方法-确定该实例和 另一个指定的String对象具有相同的值。(http://msdn.microsoft.com/en-us/library/858x0yyx.aspx) About ==—虽然string是引用类型,但相等操作符(==和 !=)的定义是为了比较字符串对象的值,而不是 参考文献这使得字符串相等性的测试更加直观。(http://msdn.microsoft.com/en-en/library/362314fe.aspx)

但如果你的一个字符串实例是空的,这些方法的工作方式是不同的:

string x = null;
string y = "qq";
if (x == y) // returns false
    MessageBox.Show("true");
else
    MessageBox.Show("false");

if (x.Equals(y)) // returns System.NullReferenceException: Object reference not set to an instance of an object. - because x is null !!!
    MessageBox.Show("true");
else
    MessageBox.Show("false");

很大一部分开发人员很可能来自Java背景,使用==比较字符串是错误的,而且不起作用。

在c#中,(对于字符串)没有(实际的)区别,只要它们的类型是字符串。

如果它们的类型是object或T,那么在这里可以看到其他关于泛型方法或操作符重载的回答,因为你肯定想使用Equals方法。

==和String之间有一个微妙但非常重要的区别。=方法:

class Program
{
    static void Main(string[] args)
    {
        CheckEquality("a", "a");
        Console.WriteLine("----------");
        CheckEquality("a", "ba".Substring(1));
    }

    static void CheckEquality<T>(T value1, T value2) where T : class
    {
        Console.WriteLine("value1: {0}", value1);
        Console.WriteLine("value2: {0}", value2);

        Console.WriteLine("value1 == value2:      {0}", value1 == value2);
        Console.WriteLine("value1.Equals(value2): {0}", value1.Equals(value2));

        if (typeof(T).IsEquivalentTo(typeof(string)))
        {
            string string1 = (string)(object)value1;
            string string2 = (string)(object)value2;
            Console.WriteLine("string1 == string2:    {0}", string1 == string2);
        }
    }
}

产生如下输出:

value1: value2: value1 == value2: True value1.Equals (value2):真的 string1 == string2: True ---------- value1: value2: value1 == value2: False value1.Equals (value2):真的 string1 == string2: True

可以看到==运算符对两个明显相等的字符串返回false。为什么?因为泛型方法中使用的==运算符被解析为System定义的op_equal方法。对象(该方法在编译时拥有的T的唯一保证),这意味着它是引用相等而不是值相等。

当有两个值类型为System时。String,则==具有值相等语义,因为编译器将==解析为System.String。op_equal代替System.Object.op_equal。

所以为了安全起见,我几乎总是使用String。我总是得到我想要的值相等语义。

如果其中一个值为null,为了避免nullreferenceexception,我总是使用静态String。=方法:

bool true = String.Equals("a", "ba".Substring(1));

我一直在碰壁,试图解决一个错误,因为我读了这篇文章,得出的结论是,在实践中没有什么有意义的区别,所以我把这个链接贴在这里,以防其他人发现他们从==和=中得到不同的结果。

Object == equal失败,但. equals成功。这有道理吗?

string a = "x";
string b = new String(new []{'x'});

Console.WriteLine("x == x " + (a == b));//True
Console.WriteLine("object x == x " + ((object)a == (object)b));//False
Console.WriteLine("x equals x " + (a.Equals(b)));//True
Console.WriteLine("object x equals x " + (((object)a).Equals((object)b)));//True