【问题标题】:How to compare custom generic List<> in C#?如何比较 C# 中的自定义泛型 List<>?
【发布时间】:2011-03-20 12:35:45
【问题描述】:

我有 2 个 class A 列表,A 已实现 Equals(object obj)GetHashCode() 这两种方法正常工作,代码如下。

class A
{
    public string TEST 
    {
        get;
        set;
    }

    public override bool Equals(object obj)
    {
        return ((A)obj).TEST == this.TEST;
    }

    public override int GetHashCode() 
    {
        return this.TEST.GetHashCode();
    }
}

我有 2 个此类列表,firstList = { X1, X2, X3 }secondList = { X1, X2, Y1 }。当我使用firstList.Except(secondList) 时,它总是返回 firstList 中的所有元素,secondList.Except(firstList) 也返回 secondList 中的所有元素,如下所示。

var test1 = firstList.Except(secondList).ToList(); // test1 = all elements of firstList
var test2 = secondList.Except(firstList).ToList(); // test2 = all elements of secondList

我想知道如何解决这个问题?

【问题讨论】:

  • TEST 属性有什么用?
  • 此代码无法编译。测试没有类型。
  • TEST 是字符串,我已经修好了 =)
  • Except 根据您的示例类结构对我来说表现正确。请发布无法正常工作的完整代码示例。

标签: c# list ienumerable


【解决方案1】:

你可以像这样使用IEquatable&lt;&gt;接口

public class Test : IEquatable<Test>
{
    public string result;
    public Test(string result) { this.result = result; }
    public bool Equals(Test other)
    {
        return result.Equals(other.result);
    }
    //No need to override Equals(object obj), GetHashCode()
}

然后当您检查时,请执行以下操作

List<Test> FirstTests = ...
List<Test> SecondTests = ...

List<Test> Result = FirstTests.FindAll(delegate(Test item)
{
    return SecondTests.Contains(item);
});

对于上面给出的示例,它有效。我只是喜欢使用匿名方法。

【讨论】:

  • 结果字段是否应该公开?
  • 没有。关键是 Test 就像一个结果的包装器,因为 Equals() 可以访问私有成员,所以它不应该是公共的。
【解决方案2】:

查找 lambda 表达式和 LINQ。

【讨论】:

    【解决方案3】:

    我不知道您的 TEST 类型。 (示例代码不起作用,因为您的属性没有指定类型。)如果 TEST 是引用类型(类),则必须将它们与 Equals 进行比较,而不是“=”。

    这行得通:

       [TestClass]
       public class UnitTest1 {
          class MyString {
             public MyString(string value) {
                _value = value;
             }
             string _value;
             public override int GetHashCode() {
                return _value.GetHashCode();
             }
             public override bool Equals(object obj) {
                MyString other = obj as MyString;
                if (other != null)
                   return other._value == this._value;
                return false;
             }
          }
    
          [TestMethod]
          public void TestMethod1() {
             List<MyString> list1 = new List<MyString> {
                new MyString("1"),
                new MyString("2"),
             };
    
             List<MyString> list2 = new List<MyString> {
                new MyString("2"),
                new MyString("3"),
             };
    
             MyString removed = list1[1];
             var result = list1.Except(list2);
             Assert.AreEqual(1, result.Count());
             Assert.IsFalse(result.Contains(removed));
          }
       }
    

    【讨论】:

    • 如果 TEST 是字符串怎么办?我可以使用 obj.TEST == this.TEST 吗?
    • 因为字符串是“非常特别”的东西,所以它会起作用。我将示例更改为字符串。
    • 如果 TEST 是字符串,我需要使用 Equals,== 总是返回 false,即使它具有相同的值。
    猜你喜欢
    • 1970-01-01
    • 2020-05-21
    • 2017-02-07
    • 2010-11-03
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多