我对引用类型中的内容相等性有些困惑。在这两种情况下,我都没有压倒平等——那么为什么行为不同。
参见 2 个简单的代码示例:
示例 1:返回 True
class Program
{
static void Main(string[] args)
{
object o1 = "ABC";
object o2 = "ABC";
Console.WriteLine("object1 and object2: {0}", o1.Equals(o2));
}
}
示例 2:两个语句都返回 False
class Program
{
static void Main(string[] args)
{
Person person1 = new Person("John");
Person person2 = new Person("John");
Console.WriteLine("person1 and person2: {0}", person1.Equals(person2));
Console.WriteLine("person1 and person2: {0}", ((object)person1).Equals((object)person2));
Console.ReadLine();
}
}
public class Person
{
private string personName;
public Person(string name)
{
this.personName = name;
}
}
最佳答案
这里有两个作用:
字符串实习意味着实际上即使您执行引用相等性检查,您仍然会看到
True
。您可以像这样修复它:object o1 = new StringBuilder("ABC").ToString(); object o2 = new StringBuilder("ABC").ToString();
System.String
overrides theEquals
method比较字符串的内容:This method performs an ordinal (case-sensitive and culture-insensitive) comparison.
你可以在这里看到区别:
object o1 = new StringBuilder("ABC").ToString(); object o2 = new StringBuilder("ABC").ToString(); Console.WriteLine(o1.Equals(o2)); // Prints True due to overriding Console.WriteLine(ReferenceEquals(o1, o2)); // Prints False
你的类没有覆盖Equals
,所以你得到了default implementation in Object
,也就是比较引用:
If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method.
您可以通过覆盖 Equals
相当轻松地解决这个问题:
// It's easier to implement equality correctly on sealed classes
public sealed class Person
{
private readonly string personName;
public Person(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
this.personName = name;
}
public override bool Equals(object other)
{
Person person = other as Person;
return person != null && person.personName.Equals(personName);
}
// Must override GetHashCode at the same time...
public override int GetHashCode()
{
// Just delegate to the name here - it's the only thing we're
// using in the equality check
return personName.GetHashCode();
}
}
请注意,在 Equals
实现中,我们可以使用:
return person != null && person.personName == personName;
... 因为 string
也 重载了 ==
运算符。但那是另一回事:)
关于c# - 引用类型相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18236828/