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

代码如下:

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

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

你知道为什么会这样吗?


当前回答

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

其他回答

注意,在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。

首先,两者有区别。对数字的

> 2 == 2.0
True

> 2.Equals(2.0)
False

对于字符串

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

在这两种情况下,==比.Equals更有用

因为到目前为止还没有提到. 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。

= =操作符

如果操作数为值类型且值相等,则返回true否则为false。 如果操作数是引用类型(string除外),并且都引用同一个实例(同一对象),则返回true否则返回false。 如果操作数为字符串类型且值相等,则返回true否则返回false。

.Equals

如果操作数是引用类型,它执行引用相等,即如果两个操作数都引用同一个实例(同一个对象),则返回true否则返回false。 如果操作数是值类型,那么与==运算符不同,它首先检查它们的类型,如果它们的类型相同,它执行==运算符,否则返回false。

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

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

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

更多的解释请看这里。