我在silverlight应用程序中有一个比较2个字符串的条件,由于某种原因,当我使用==时,它返回false而. equals()返回true。

代码如下:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

你知道为什么会这样吗?


当前回答

@BlueMonkMN早前的回答还有另一个层面。额外的维度是,@Drahcir的标题问题的答案也取决于我们如何得到字符串值。说明:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));

Console.WriteLine("\n  Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Console.WriteLine("\n  Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

输出结果为:

True True True

  Case1 - A method changes the value:
False True True
False False True

  Case2 - Having only literals allows to arrive at a literal:
True True True
True True True

其他回答

非常棒的答案和例子!

我想补充一下两者之间的根本区别,

像==这样的操作符不是多态的,而Equals是

记住这个概念,如果你算出任何例子(通过查看左手和右手引用类型,并检查/知道类型是否确实重载了==操作符和重写了Equals),你肯定会得到正确的答案。

当==用于object类型的表达式时,它将解析为System.Object.ReferenceEquals。

Equals只是一个虚方法,因此将使用重写的版本(对于字符串类型比较内容)。

当比较对象引用和字符串时(即使对象引用引用了字符串),特定于字符串类的==操作符的特殊行为将被忽略。

Normally (when not dealing with strings, that is), Equals compares values, while == compares object references. If two objects you are comparing are referring to the same exact instance of an object, then both will return true, but if one has the same content and came from a different source (is a separate instance with the same data), only Equals will return true. However, as noted in the comments, string is a special case because it overrides the == operator so that when dealing purely with string references (and not object references), only the values are compared even if they are separate instances. The following code illustrates the subtle differences in behaviors:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;  // Notice: set to object variable!

Console.WriteLine($"{object.ReferenceEquals(s1, s2)} {s1 == s2} {s1.Equals(s2)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s3)} {s1 == s3} {s1.Equals(s3)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s4)} {s1 == s4} {s1.Equals(s4)}");

输出结果为:

True True True     // s1, s2
False True True    // s1, s3
False False True   // s1, s4

简介:

Variables .ReferenceEquals == .Equals
s1, s2 True True True
s1, s3 False True True
s1, s4 False False True

这是由于值相等(equal方法)和引用相等(==运算符),因为equal方法检查值,而相同的==检查引用。

==运算符覆盖https://referencesource.microsoft.com/上string类内可用的代码

现在更容易理解了,equal方法也有两个实现一个来自string类本身,一个来自object类。它对性能的影响以及我也运行一些基本的代码,并试图理解基准测试。

我分享下面的结果,如果我错了,请纠正或建议。有3种情况,我对所有情况运行了相同的代码,这就是结果。

情况1:这里我使用的是字符串。相等的方法比较两个字符串和两个字符串有相同的值。string.equals (a, b)

第一次运行:5608195 tick

第二次运行:5529387个刻度

第三次运行:5622569滴答

总蜱数:16760151

情况2:这里我使用的是字符串。Equal()方法(重载的一个)用于比较两个字符串,并且两个字符串具有相同的值。 a.equals (b)

第一次运行:6738583滴答

第二轮:6452927

第三轮:7168897个刻度

总蜱虫= 20360407

情况3:这里我使用==操作符比较2个字符串,两个字符串都有相同的值。 a = =

第一次运行:6652151滴答

第二次运行:7514300个tick

第三轮:7634606滴答

总蜱虫= 21801057

class Program
{
    private static int count;
    static string a = "abcdef";
    static string b = "abcdef";
    static void Main(string[] args)
    {            

        for (int j = 1; j <= 3; j++)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 1; i <= 1000; i++)
            {
                checkString();
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedTicks);
        }
        Console.ReadLine();

    }
    public static void checkString()
    {
        for (int i = 1; i <= 100000; i++)
        {
            if (a==b)
                count++;
        }
    }
}

因为到目前为止还没有提到. equal方法的静态版本,所以我想在这里添加它来总结和比较这3种变体。

MyString.Equals("Somestring"))          //Method 1
MyString == "Somestring"                //Method 2
String.Equals("Somestring", MyString);  //Method 3 (static String.Equals method) - better

其中MyString是一个变量,它来自代码中的其他地方。

背景信息和总结:

在Java中,不应该使用==来比较字符串。我提到这一点是为了防止你需要使用两种语言 让你知道在c#中使用==也可以用更好的东西代替。

在c#中,使用方法1或方法2比较字符串没有实际区别,只要两者都是字符串类型。但是,如果一个为空,一个为其他类型(如整数),或者一个表示具有不同引用的对象,那么,正如最初的问题所示,您可能会遇到比较相等的内容可能不会返回您所期望的结果。

建议解决方案:

因为在比较时使用==与使用. equals不完全相同,所以可以使用静态String。改为= method。这样,如果两边不是相同的类型,您仍然可以比较内容,如果其中一方为空,则可以避免异常。

   bool areEqual = String.Equals("Somestring", MyString);  

写起来有点麻烦,但在我看来,使用起来更安全。

以下是从微软复制的一些信息:

public static bool Equals (string a, string b);

参数

一个字符串

要比较的第一个字符串,或null。

b字符串

要比较的第二个字符串,或null。

返回布尔值

如果a的值与b的值相同,则为真;否则,假的。如果a和b都为空,则该方法返回true。