1

我会尽我所能解释我在这里做什么——我已经使用过这种方法几次,但从来没有感觉那么好。我相信一定有更好的方法,请赐教。

class MyObject
{
    public int Id { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (ReferenceEquals(this, obj))
        {
            return true;
        }
        if (obj.GetType() != typeof(MyObject))
        {
            return false;
        }
        return ((MyObject)obj).Id == Id;
    }

    public override int GetHashCode()
    {
        return Id;
    }
}

[Test]
public void Blah()
{
    IDictionary<object, MyObject> duplicateMergerDict = new Dictionary<object, MyObject>();

    MyObject dup1 = new MyObject { Id = 0, Name = "Smith" };
    MyObject dup2 = new MyObject { Id = 0, Name = "Collins" };
    MyObject nonDup = new MyObject { Id = 1, Name = "Smith" };

    IEnumerable<MyObject> test =
        new[] { dup1, dup2, nonDup };

    foreach (var myObject in test)
    {
        MyObject existing;
        if (duplicateMergerDict.TryGetValue(myObject, out existing))
        {
            existing.Name = string.Format("{0} {1}", existing.Name, myObject.Name);
        }
        else
        {
            duplicateMergerDict.Add(myObject, myObject);
        }
    }

    Assert.That(duplicateMergerDict.Count, Is.EqualTo(2));

    Assert.That(duplicateMergerDict[dup1], Is.SameAs(dup1));
    Assert.That(duplicateMergerDict[dup2], Is.SameAs(dup1));

    Assert.That(dup1.Name, Is.EqualTo("Smith Collins"));

    Assert.That(duplicateMergerDict[nonDup], Is.SameAs(nonDup));
}

基本上我想使用 GetHashCode 和 Equals 覆盖来累积重复条目。(或者我应该使用复合键对象 - 即使是比这更复杂的情况?)。上面的方法看起来很乱,但也许这是最好的方法?

比我更聪明的人可以告诉我在哪里可以改进吗?

谢谢。

4

1 回答 1

3

基本上我想使用 GetHashCode 和 Equals 覆盖来累积重复条目。

你不能。这不是他们的目的。他们只是为了找到一把钥匙,测试它是否相等。你当然不应该在那里改变任何东西。

您使用的方法TryGetValue有效,但它要求您的值是可变的,这在 IMO 中并不令人愉快。你可能想看看ConcurrentDictionary<,>,它有一个方便的AddOrUpdate方法,听起来就像你想要的那样。

于 2012-11-29T15:05:05.727 回答