c# - 引用类型相等

标签 c#

我对引用类型中的内容相等性有些困惑。在这两种情况下,我都没有压倒平等——那么为什么行为不同。

参见 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 the Equals 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/

相关文章:

c# - Python XML Parse(使用模式生成数据集)

c# - asp.net 将行从一个数据表复制到另一个

c# - 组合框 SelectedIndexChanged 事件 : how to get the previously selected index?

c# - 如何获取特定属性的 PropertyInfo?

c# - HTTP GET 请求和 XML 应答

c# - 如何从一组整数组中找到最小的不同组?

c# - 用每月的第一天分配变量

c# - 打开位置设置页面或提示用户启用位置

c# - 如何在 Visual Studio C# 命令 MySqlConnection() 上执行“"SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO”;

c# - NAudio - 从指定位置搜索和导航播放