按特定值比较子列表与父列表
Compare list of child to list of parent by specific value
我有 2 个列表,第一个是父对象,第二个是子对象。子对象有额外的 属性,我想将其与父对象 class 的 属性 进行比较。
这是例子
public class Parent
{
public int X { get; set; }
}
public class Child : Parent
{
public int Y { get; set; }
}
public class ClassXCompare : IEqualityComparer<Parent>
{
public bool Equals(Parent x, Parent y)
{
var child = (Child)y;
return x.X == child.Y;
}
public int GetHashCode(Parent parent)
{
int parentXhash = parent.X.GetHashCode();
// Calculate the hash code for the product.
return parentXhash ;
}
}
现在如果我测试以下内容,它总是失败
var parentList= new List<Parent>
{
new Parent {X = 5},
new Parent {X = 6}
};
var childList= new List<Child>
{
new Child {Y = 5},
new Child {Y = 6}
};
var compare = new ClassXCompare();
var diff = parentList.Except(childList, compare);
Assert.IsTrue(!diff.Any()); // Fail ???
我认为我的问题出在 GetHashCode 函数
知道如何解决这个问题吗?
(Please ignore the design of the application this is simplified
version of the issue)
仅当 GetHashCode returns 两个项目的值相同时才会调用 Set/Dictionary 中的等于 - 参见 General advice and guidelines on how to properly override object.GetHashCode()。修复它的最简单方法是使用类似这样的方法,其中 child 值用于计算 HashCode
(如果可用):
public class ClassXCompare : IEqualityComparer<Parent>
{
public bool Equals(Parent x, Parent y)
{
var child = (Child)y;
return x.X == child.Y;
}
public int GetHashCode(Parent parent)
{
var child = parent as Child;
return child == null ?
parent.X : child.Y.
}
}
虽然如果你必须处理多个 child 类.
不确定是否有一种简单的方法来处理多个 child 类,除了一些自定义 generic IEqualityComparer,即使那样也只会缩短一点。
P.S. 另外我不确定第二个参数是否总是 Child
(怀疑标准涵盖了它,尽管当前在这种特殊用法似乎以适当的方式工作),因此您可能必须 IEqualityComparer
对参数的顺序更加宽松。
这真是糟糕的设计。在比较器中转换为特定类型的需要会给您带来无穷无尽的麻烦。
但是,下面的代码通过了。请注意不同的转换方法、null 检查和 except 行上列表的顺序。
问题是 Child 实例没有设置 X 并且 Except 方法将值传递给 Equals 的顺序意味着 "x" 是 Child 而不是 "y"。
这可能 "work" 但您应该认真地重新考虑您的设计。
public class Parent
{
public int X { get; set; }
}
public class Child : Parent
{
public int Y { get; set; }
}
public class ClassXCompare : IEqualityComparer<Parent>
{
public bool Equals(Parent x, Parent y)
{
var child = y as Child;
return child != null && x.X == child.Y;
}
public int GetHashCode(Parent parent)
{
var c = parent as Child;
if (c == null)
return parent.X.GetHashCode();
else
return c.Y.GetHashCode();
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var parentList = new List<Parent>
{
new Parent {X = 5},
new Parent {X = 6}
};
var childList = new List<Child>
{
new Child {Y = 5},
new Child {Y = 6}
};
var compare = new ClassXCompare();
var diff = childList.Except(parentList, compare);
Assert.IsTrue(!diff.Any()); // Fail ???
}
}
我有 2 个列表,第一个是父对象,第二个是子对象。子对象有额外的 属性,我想将其与父对象 class 的 属性 进行比较。
这是例子
public class Parent
{
public int X { get; set; }
}
public class Child : Parent
{
public int Y { get; set; }
}
public class ClassXCompare : IEqualityComparer<Parent>
{
public bool Equals(Parent x, Parent y)
{
var child = (Child)y;
return x.X == child.Y;
}
public int GetHashCode(Parent parent)
{
int parentXhash = parent.X.GetHashCode();
// Calculate the hash code for the product.
return parentXhash ;
}
}
现在如果我测试以下内容,它总是失败
var parentList= new List<Parent>
{
new Parent {X = 5},
new Parent {X = 6}
};
var childList= new List<Child>
{
new Child {Y = 5},
new Child {Y = 6}
};
var compare = new ClassXCompare();
var diff = parentList.Except(childList, compare);
Assert.IsTrue(!diff.Any()); // Fail ???
我认为我的问题出在 GetHashCode 函数
知道如何解决这个问题吗?
(Please ignore the design of the application this is simplified version of the issue)
仅当 GetHashCode returns 两个项目的值相同时才会调用 Set/Dictionary 中的等于 - 参见 General advice and guidelines on how to properly override object.GetHashCode()。修复它的最简单方法是使用类似这样的方法,其中 child 值用于计算 HashCode
(如果可用):
public class ClassXCompare : IEqualityComparer<Parent>
{
public bool Equals(Parent x, Parent y)
{
var child = (Child)y;
return x.X == child.Y;
}
public int GetHashCode(Parent parent)
{
var child = parent as Child;
return child == null ?
parent.X : child.Y.
}
}
虽然如果你必须处理多个 child 类.
不确定是否有一种简单的方法来处理多个 child 类,除了一些自定义 generic IEqualityComparer,即使那样也只会缩短一点。
P.S. 另外我不确定第二个参数是否总是 Child
(怀疑标准涵盖了它,尽管当前在这种特殊用法似乎以适当的方式工作),因此您可能必须 IEqualityComparer
对参数的顺序更加宽松。
这真是糟糕的设计。在比较器中转换为特定类型的需要会给您带来无穷无尽的麻烦。
但是,下面的代码通过了。请注意不同的转换方法、null 检查和 except 行上列表的顺序。
问题是 Child 实例没有设置 X 并且 Except 方法将值传递给 Equals 的顺序意味着 "x" 是 Child 而不是 "y"。
这可能 "work" 但您应该认真地重新考虑您的设计。
public class Parent
{
public int X { get; set; }
}
public class Child : Parent
{
public int Y { get; set; }
}
public class ClassXCompare : IEqualityComparer<Parent>
{
public bool Equals(Parent x, Parent y)
{
var child = y as Child;
return child != null && x.X == child.Y;
}
public int GetHashCode(Parent parent)
{
var c = parent as Child;
if (c == null)
return parent.X.GetHashCode();
else
return c.Y.GetHashCode();
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var parentList = new List<Parent>
{
new Parent {X = 5},
new Parent {X = 6}
};
var childList = new List<Child>
{
new Child {Y = 5},
new Child {Y = 6}
};
var compare = new ClassXCompare();
var diff = childList.Except(parentList, compare);
Assert.IsTrue(!diff.Any()); // Fail ???
}
}