我在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

其他回答

注意,在c#中有两种不同类型的等式

1-值相等(对于int, DateTime和struct等值类型)

2-引用平等(对象)

有两个基本的标准协议来实现相等性检查。

1- ==和!=运算符。

2- virtual Equals方法。

==和!=是静态解析的,这意味着c#将在编译时决定哪种类型将执行比较。

例如值类型

 int x = 50;
 int y = 50;
 Console.WriteLine (x == y); // True

但是对于参考类型

 object x = 50;
 object y = 50;
 Console.WriteLine (x == y); // False 

Equals()最初在运行时根据操作数的实际类型解析。

例如,在下面的例子中,在运行时,将决定Equals()将应用于int值,结果为真。

object x = 5;
object y = 5;
Console.WriteLine (x.Equals (y)); // True

但是,对于引用类型,它将使用引用相等性检查。

MyObject x = new MyObject();
MyObject y = x;
Console.WriteLine (x.Equals (y)); // True

注意Equals()对struct使用结构比较,这意味着它对struct的每个字段调用Equals。

==和. 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

Equals()和==是否相同取决于实现。因为c#允许用户分别为Equals()和==设置不同的行为。

    class CompareTest
    {
        public readonly int val;

        public CompareTest(int val)
        {
            this.val = val;
        }

        public override bool Equals(object obj)
        {
            return obj is CompareTest test && this.val == test.val;
        }

        public override int GetHashCode()
        {
            return val;
        }

        public static bool operator == (CompareTest a, object b)
        {
            return Equals(a, b);
        }

        public static bool operator != (CompareTest a, object b)
        {
            return !(a == b);
        }
    }

在本例中,我使Equals()和==具有相同的行为。但如果我让他们不一样呢?例如:

        public static bool operator == (CompareTest a, object b)
        {
            return false;
        }

Equals()正常工作,但==永远不会工作。

此外,虽然我让它们具有相同的行为,但仍然有一个区别:哪个==函数将被调用取决于左边的值:

        Compare Test a = new CompareTest(1);
        object b = new CompareTest(1);
        CompareTest c = new CompareTest(1);
        Debug.Log("AB " + (a == b)); // true
        Debug.Log("BA " + (b == a)); // false! because it calls object's == function 
        Debug.Log("AC " + (a == c)); // true
        Debug.Log("CA " + (c == a)); // true

给答案再加一分。

. equalsto()方法提供了比较区域性和区分大小写的方法。

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

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