在 C# 中对记录进行相等性检查时忽略私有成员变量

Ignore private member variables when doing equality checks with records in C#

我有一个记录定义,我只想检查记录定义中 public/specific 成员变量的相等性。如果没有自定义 Equals 函数,我还没有找到一种方法来执行此操作,如果有另一个更好的解决方案,我宁愿不要这样做。对记录中的私有成员变量是否是错误模式的任何思考,也表示赞赏。

等式成立的记录示例:

        public record Test
        {
            public string Variable { get; init; }

            public Test(string someValue)
            {
                Variable = someValue;
            }
        }

        [Fact]
        public void RecordTest()
        {
            var test1 = new Test("hello");
            var test2 = new Test("hello");

            Assert.Equal(test1, test2); // Passes
        }

我希望它是真的但事实并非如此的记录示例:

       public record Test
        {
            // I believe this is causing it to fail, can it be ignored somehow?
            private readonly List<string> _list = new();

            public string Variable { get; init; }

            public Test(string someValue)
            {
                Variable = someValue;
                _list.Add(someValue);
            }
        }

        [Fact]
        public void RecordTest()
        {
            var test1 = new Test("hello");
            var test2 = new Test("hello");

            Assert.Equal(test1, test2); // Fails
        }

microsoft documentation 你可以读到这个:

For records, value equality means that two variables of a record type are equal if the types match and all property and field values match. For other reference types such as classes, equality means reference equality. That is, two variables of a class type are equal if they refer to the same object. Methods and operators that determine equality of two record instances use value equality.

此处的列表需要具有相同的引用才能使等式生效。 我认为使用相等比较器或重写相等是最好的方法。

如何创建您自己的 class 来包装您的列表,并实现您自己的对象 Equals 和 GetHashCode 覆盖,以及实现 IEquatable 接口。然后在记录中使用您自己的包装器。类似于:

public class ListWrapper : IEquatable<ListWrapper>
{
    private readonly List<string> _list = new();

    public void Add(string item) => _list.Add(item);

    public bool Equals(ListWrapper other)
    {
        return _list.SequenceEqual(other._list);
    }

    // you may or may not want to override object Equals and GetHashCode.
}


public record Test
{
    private readonly ListWrapper _list = new();

    public string Variable { get; init; }

    public Test(string someValue)
    {
        Variable = someValue;
        _list.Add(someValue);
    }
}