联接对象集合上的多个属性的正确方法
本文关键字:属性 方法 对象 集合 | 更新日期: 2023-09-27 18:36:19
假设我有一个对象,其中以下 3 个属性(其他属性已被省略)构成一个"唯一"的计划对象(如果它们等于另一个 Plan 对象中的相同值)。
public class Plan
{
public int ID { get; set; }
public Plan Parent { get; set; }
public ID SomeOtherProperty { get; set; }
}
这是我Join
代码,其中省略了Join
运算符的匿名方法(我知道默认情况下这段代码不起作用):
oldPlans
.Join(newPlans, o => o, n => n, (o, n) => new { Old = o, New = n })
.ForEach(e =>
{
...
});
我想对两个 Plan 对象的集合执行 C# Join
。我知道一种方法是对连接属性使用匿名方法,写出这三个属性。
但是有没有不同的方法?我可以覆盖GetHashCode
吗?当我尝试这样做时,它似乎并没有这样称呼它。我也尝试过覆盖 Equals,但它似乎也没有这么称呼。我是否应该覆盖==
和!=
运算符?我可以显式调用键选择器字段的.GetHashCode()
吗(假设我覆盖了它)?
是否可以让此 Join 检查这两个对象的相等性,而不会使键选择器复杂化?谢谢。
你的代码对我来说很好用 - 通过 ReferenceSource 跟踪,默认比较最终使用的是调用 Equals()
的 ObjectEqualityComparer,所以你的想法是正确的。
因此,这归结为您如何实施Equals
和GetHashCode
。如果覆盖一个,则应覆盖两者,如 MSDN 所述:
警告:如果重写 GetHashCode 方法,则还应重写 Equals,反之亦然。如果在测试两个对象的相等性时重写的 Equals 方法返回 true,则重写的 GetHashCode 方法必须为这两个对象返回相同的值。
请注意,您的ID
类还需要正确处理这两种方法,因为Plan
应该使用它来检查相等性并获取哈希代码。
这个程序对我有用,只打印带有ID=2
的第二个条目(请注意,为了简单起见,我做了SomeOtherProperty
和int
,但这不会影响方法或代码):
class Program
{
public class Plan
{
public int ID { get; set; }
public Plan Parent { get; set; }
public int SomeOtherProperty { get; set; }
// added to show we don't care about this
public string IgnoreMe { get; set; }
public Plan(int id, int other, Plan parent, string ignore)
{
this.ID = id;
this.SomeOtherProperty = other;
this.Parent = parent;
this.IgnoreMe = ignore;
}
public override bool Equals(object obj)
{
Plan other = (Plan)obj;
// just check the relevant properties
return this.ID == other.ID
&& this.SomeOtherProperty == other.SomeOtherProperty
&& this.Parent == other.Parent;
// .. or alternatively
//return (new { ID, SomeOtherProperty, Parent })
// .Equals(new { other.ID, other.SomeOtherProperty, other.Parent });
}
// nicked from http://stackoverflow.com/a/4630550/1901857
public override int GetHashCode()
{
return new { ID, SomeOtherProperty, Parent }.GetHashCode();
}
// just to help debug
public override string ToString()
{
return string.Format("[ID: {0}, Other:{1}, Parent:{2}]", ID, SomeOtherProperty, Parent);
}
}
static void Main(string[] args)
{
var parentPlans = new Plan[] {
new Plan(101, 2, null, "parent1"),
new Plan(102, 3, null, "parent2"),
new Plan(103, 4, null, "parent3"),
new Plan(104, 5, null, "parent4")
};
List<Plan> oldPlans = new List<Plan>(new Plan[] {
new Plan(1, 2, parentPlans[0], "old1"),
new Plan(2, 3, parentPlans[1], "old2"),
new Plan(3, 4, parentPlans[2], "old3"),
new Plan(4, 5, parentPlans[3], "old4")
});
List<Plan> newPlans = new List<Plan>(new Plan[] {
new Plan(11, 2, parentPlans[0], "new1"), // different ID
new Plan(2, 3, parentPlans[1], "new2"), // same
new Plan(3, 14, parentPlans[2], "new3"), // different other ID
new Plan(4, 5, parentPlans[2], "new4") // different parent
});
foreach (var e in
oldPlans.Join(newPlans, o => o, n => n, (o, n) => new { Old = o, New = n }))
{
Console.WriteLine(e.Old + " / " + e.New);
};
}
}
如果您认为您的Equals
和GetHashCode
实现应该有效,那么请将它们发布在问题中,也许它们不太正确。