简体   繁体   English

如何使用自定义比较器为键从通用词典中获取值?

[英]How to get a value from a generic dictionary using a custom comparer for the key?

I have a generic dictionary of objects and want to use a custom comparer to update the value in the dictionary. 我有一个通用的对象字典,想使用自定义比较器更新字典中的值。

myObjects contains a dictionary of objects and the value is the number of times that object exists. myObjects包含对象的字典,值是该对象存在的次数。 Note that the value may be incremented numerous times using different comparators or removed altogether. 注意,可以使用不同的比较器将该值增加多次或完全删除。

testObject is my custom object. testObject是我的自定义对象。

customComparer is a dynamically changing comparer based on the type of testObject. customComparer是一个基于testObject类型的动态变化的比较器。 but all comparers are of the type IEqualityComparer<MyObject> 但是所有比较器的类型均为IEqualityComparer<MyObject>

IDictionary<MyObject, int> myObjects;
var testObject;
var customComparer;

if (myObjects.Keys.Contains(testObject, customComparer))
{
    //get the value, if its > 1 then decrement the value
    //else remove the entry entirely
    //not sure how to get the value based on my custom comparer??

    //this code below does not work because it requires the custom comparer
    //var occurrences = myObjects[testObject];
    //if (occurrences > 1)
    //    myObjects[testObject]--;
    //else
    //    myObjects.Remove(testObject);
}
else
{
    myObjects.Add(testObject, 1);
}

I can use Keys.Contains to determine if the object exists with custom comparer but then i'm not sure how to update the value? 我可以使用Keys.Contains来确定对象是否存在自定义比较器,但是我不确定如何更新该值?

When you create the dictionary you should provide your custom IEqualityComparer in the constructor . 创建字典时,应在构造函数中提供自定义IEqualityComparer You can't change the equality comparer after the dictionary is constructed. 构建字典后,您将无法更改相等比较器。

You could iterate over the key value pairs until you find a key that matches according to your custom comparer, but then you aren't taking advantage of the features that a Dictionary provides. 可以遍历键值对,直到找到根据您的自定义比较器匹配的键为止,但是这样您就无法利用Dictionary提供的功能。

There was no quick imlpementation for this. 没有对此的快速干预。 Instead, I created a wrapper IEqualityComparer that housed numerous internal equality comparers. 相反,我创建了一个包装器IEqualityComparer,其中包含许多内部相等比较器。 The wrapper overwrote the Equals and GetHashCode methods which picked the appropriate internal dictionary of equality comparers based on a property from the comparison object. 包装器重写了Equals和GetHashCode方法,该方法根据比较对象的属性选择了适当的内部比较器内部字典。

public class WrapperComparer : IEqualityComparer<MyObject>
{
    private IDictionary<string, IEqualityComparer<MyObject>> _myComparerList;

    public bool Equals(MyObject x, MyObject y)
    {
        var comparer = _myComparerList[x.SomeProperty];
        return comparer.Equals(x, y);
    }

    public bool GetHashCode(MyObject obj)
    {
        var comparer = _myComparerList[obj.SomeProperty];
        return comparer.GetHashCode(obj);
    }
}

Then the comparison works... 然后比较工作...

var testObject;
var customComparer = new WrapperComparer(list of comparers here);
IDictionary<MyObject, int> myObjects = 
    new Dictionary<MyObject, int>(customComparer);

if (myObjects.ContainsKey(testObject))
{
    var occurrences = myObjects[testObject];
    if (occurrences > 1)
      myObjects[testObject]--;
    else
      myObjects.Remove(testObject);
}
else
{
    myObjects.Add(testObject, 1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM