Why would you use String.Equals over ==? [duplicat

2018-12-31 14:16发布

This question already has an answer here:

I recently was introduced to a large codebase and noticed all string comparisons are done using String.Equals() instead of ==

What's the reason for this, do you think?

标签: c# string equals
8条回答
孤独寂梦人
2楼-- · 2018-12-31 14:46

It's entirely likely that a large portion of the developer base comes from a Java background where using == to compare strings is wrong and doesn't work.

In C# there's no (practical) difference (for strings) as long as they are typed as string.

If they are typed as object or T then see other answers here that talk about generic methods or operator overloading as there you definitely want to use the Equals method.

查看更多
高级女魔头
3楼-- · 2018-12-31 14:49

Both methods do the same functionality - to compare values. As it is written in MSDN:

But if one of your string instances is null, these methods are working differently:

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");
查看更多
几人难应
4楼-- · 2018-12-31 14:56

I've just been banging my head against a wall trying to solve a bug because I read this page and concluded there was no meaningful difference when in practice there is so I'll post this link here in case anyone else finds they get different results out of == and equals.

Object == equality fails, but .Equals succeeds. Does this make sense?

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
查看更多
听够珍惜
5楼-- · 2018-12-31 14:59

There is one subtle but very important difference between == and the String.Equals methods:

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);
        }
    }
}

Produces this output:

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

You can see that the == operator is returning false to two obviously equal strings. Why? Because the == operator in use in the generic method is resolved to be the op_equal method as defined by System.Object (the only guarantee of T the method has at compile time), which means that it's reference equality instead of value equality.

When you have two values typed as System.String explicitly, then == has a value-equality semantic because the compiler resolves the == to System.String.op_equal instead of System.Object.op_equal.

So to play it safe, I almost always use String.Equals instead to that I always get the value equality semantics I want.

And to avoid NullReferenceExceptions if one of the values is null, I always use the static String.Equals method:

bool true = String.Equals("a", "ba".Substring(1));
查看更多
素衣白纱
6楼-- · 2018-12-31 14:59

I want to add that there is another difference. It is related to what Andrew posts.

It is also related to a VERY annoying to find bug in our software. See the following simplified example (I also omitted the null check).

public const int SPECIAL_NUMBER = 213;

public bool IsSpecialNumberEntered(string numberTextBoxTextValue)
{
    return numberTextBoxTextValue.Equals(SPECIAL_NUMBER)
}

This will compile and always return false. While the following will give a compile error:

public const int SPECIAL_NUMBER = 213;

public bool IsSpecialNumberEntered(string numberTextBoxTextValue)
{
    return (numberTextBoxTextValue == SPECIAL_NUMBER);
}

We have had to solve a similar problem where someone compared enums of different type using Equals. You are going to read over this MANY times before realising it is the cause of the bug. Especially if the definition of SPECIAL_NUMBER is not near the problem area.

This is why I am really against the use of Equals in situations where is it not necessary. You lose a little bit of type-safety.

查看更多
回忆,回不去的记忆
7楼-- · 2018-12-31 15:06

String.Equals does offer overloads to handle casing and culture-aware comparison. If your code doesn't make use of these, the devs may just be used to Java, where (as Matthew says), you must use the .Equals method to do content comparisons.

查看更多
登录 后发表回答