C# 使相互依赖的两个类相等
我有甲级:C# 使相互依赖的两个类相等,c#,.net-core,C#,.net Core,我有甲级: public class A : IEquatable<A> { public B Owner { get; set; } public override bool Equals(object obj) { return Equals(obj as A); } public bool Equals([AllowNull] A other) { return other is A a &am
public class A : IEquatable<A>
{
public B Owner { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as A);
}
public bool Equals([AllowNull] A other)
{
return other is A a &&
EqualityComparer<B>.Default.Equals(Owner, a.Owner);
}
}
公共A类:IEquatable
{
公共B所有者{get;set;}
公共覆盖布尔等于(对象对象对象)
{
回报等于(obj作为一个整体);
}
公共布尔等于([AllowNull]A其他)
{
返回另一个是A&&
EqualityComparer.Default.Equals(Owner,a.Owner);
}
}
我有一个B级:
public class B : IEquatable<B>
{
public List<A> Children { get; set; } = new List<A>();
public override bool Equals(object obj)
{
return Equals(obj as B);
}
public bool Equals([AllowNull] B other)
{
return other is B b &&
EqualityComparer<List<A>>.Default.Equals(Children, b.Children);
}
}
公共B类:可满足
{
公共列表子项{get;set;}=new List();
公共覆盖布尔等于(对象对象对象)
{
返回等于(obj为B);
}
公共布尔等于([AllowNull]B其他)
{
返回另一个是B&&
EqualityComparer.Default.Equals(Children,b.Children);
}
}
我遇到的问题是使上述类的Equals()
方法工作。示例中的Equals()
方法由VS代码生成,但在类B的情况下总是返回false
我还尝试使用LINQ表达式(例如SequenceEqual方法),但它总是导致堆栈溢出(因为循环依赖?)
作为补充说明,我使用.NET Core 3.0运行了这个程序。因此,我设法找到了问题的答案。我刚刚实现了自己的自定义IEqualityComparer。(在下面的示例中,我将
公共Guid ID
属性添加到两个类中,以正确执行GetHashCode()
)
公共类B比较程序:IEqualityComparer
{
公共布尔等于([AllowNull]Bx[AllowNull]By)
{
如果(x为null | | y为null){返回false;}
如果(x.ID==y.ID){
返回x.Children.SequenceEqual(y.Children);
}否则{
返回false;
}
}
public int GetHashCode([DisallowNull]B obj)
{
返回obj.ID.ToString().GetHashCode();
}
}
您可以为此编写自己的自定义比较器。顺便说一句,你为什么需要这里的循环引用?@PavelAnikhouski,例如一个产品(a)和它的制造商(B)。制造商可以有许多产品,但产品只能有一个制造商,并且它们相互指向对方。至于定制比较器,我想了想,只是不知道如何,也找不到关于它们的任何信息。
public class BComparer : IEqualityComparer<B>
{
public bool Equals([AllowNull] B x, [AllowNull] B y)
{
if (x is null || y is null) {return false;}
if (x.ID == y.ID) {
return x.Children.SequenceEqual(y.Children);
} else {
return false;
}
}
public int GetHashCode([DisallowNull] B obj)
{
return obj.ID.ToString().GetHashCode();
}
}