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

代码如下:

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

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

你知道为什么会这样吗?


当前回答

当我们创建任何对象时,对象有两个部分,一个是内容,另一个是对该内容的引用。 ==比较内容和引用; Equals()只比较内容

http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq

其他回答

==和. equals都依赖于实际类型中定义的行为和调用位置上的实际类型。两者都只是方法/操作符,可以在任何类型上重写,并给定作者希望的任何行为。根据我的经验,我发现人们在对象上实现. equals却忽略了operator ==是很常见的。这意味着. equals将实际测量值是否相等,而==将测量它们是否是相同的引用。

当我处理一个定义不断变化的新类型或编写泛型算法时,我发现最佳实践如下

如果我想在c#中比较引用,我使用Object。直接使用ReferenceEquals(在泛型情况下不需要) 如果我想比较值,我使用EqualityComparer<T>。默认的

在某些情况下,当我觉得==的用法不明确时,我会显式地使用Object。在代码中引用等号以消除歧义。

Eric Lippert最近写了一篇博文,主题是为什么在CLR中有两种相等的方法。值得一读

http://blogs.msdn.com/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx

这是由于值相等(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++;
        }
    }
}

我想补充的是,如果你将对象转换为字符串,那么它将正确工作。这就是为什么编译器会给你一个警告说:

可能出现意外的参考比较;为了进行价值比较, 转换左侧以输入'string'

@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),你肯定会得到正确的答案。