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

代码如下:

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

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

你知道为什么会这样吗?


当前回答

作为对已经很好的答案的补充:这种行为不仅限于字符串或比较不同的数字类型。即使两个元素的类型对象都是相同的基础类型。“==”不行。

下面的屏幕截图显示了比较两个object {int} -值的结果

其他回答

给答案再加一分。

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

Equal和==之间的唯一区别是对象类型比较。在其他情况下,例如引用类型和值类型,它们几乎是相同的(要么都是位相等,要么都是引用相等)。

对象: Equals:位的相等 ==:引用相等

String:(equals和==对于String是相同的,但如果字符串中的一个被更改为object,则比较结果将不同) Equals:位的相等 ==:位相等

更多的解释请看这里。

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

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

The == token in C# is used for two different equality-check operators. When the compiler encounters that token, it will check whether either of the types being compared has implemented an equality-operator overload for either the specific combination types being compared(*), or for a combination of types to which both types can be converted. If the compiler finds such an overload it will use it. Otherwise, if the two types are both reference types and they are not unrelated classes (either may be an interface, or they may be related classes), the compiler will regard == as a reference-comparison operator. If neither condition applies, compilation will fail.

请注意,其他一些语言为两个相等检查操作符使用单独的令牌。在VB。例如,=令牌在表达式中仅用于可重载的相等检查操作符,而is则用作引用测试或空测试操作符。在没有覆盖相等检查操作符的类型上使用=将会失败,在测试引用是否相等或为空之外的任何目的上尝试使用Is也会失败。

(*)Types generally only overload equality for comparison with themselves, but it may be useful for types to overload the equality operator for comparison with other particular types; for example, int could have (and IMHO should have but didn't) defined an equality operators for comparison with float, so that 16777217 would not report itself equal to 16777216f. As it is, since no such operator is defined, C# will promote the int to float, rounding it to 16777216f before the equality-check operator sees it; that operator then sees two equal floating-point numbers and reports them as equal, unaware of the rounding that took place.