我在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都依赖于实际类型中定义的行为和调用位置上的实际类型。两者都只是方法/操作符,可以在任何类型上重写,并给定作者希望的任何行为。根据我的经验,我发现人们在对象上实现. 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
注意,在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。
当比较对象引用和字符串时(即使对象引用引用了字符串),特定于字符串类的==操作符的特殊行为将被忽略。
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 |
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