Как получить значение из универсального словаря, используя пользовательский компаратор для ключа? - PullRequest
0 голосов
/ 05 декабря 2011

У меня есть общий словарь объектов, и я хочу использовать пользовательский компаратор для обновления значения в словаре.

myObjects содержит словарь объектов, а значение - количество раз, которое объект существует. Обратите внимание, что значение можно увеличивать многократно с использованием различных компараторов или удалять вообще.

testObject - мой пользовательский объект.

customComparer - динамически изменяемый компаратор, основанный на типе testObject. но все компараторы имеют тип 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);
}

Я могу использовать Keys.Contains, чтобы определить, существует ли объект с помощью пользовательского компаратора, но тогда я не уверен, как обновить значение?

Ответы [ 2 ]

4 голосов
/ 05 декабря 2011

При создании словаря вы должны указать свой IEqualityComparer в конструкторе . Вы не можете изменить равенство равенства после построения словаря.

Вы можете выполнять итерацию по парам ключ-значение, пока не найдете ключ, соответствующий вашему пользовательскому компаратору, но тогда вы не воспользуетесь возможностями, которые предоставляет словарь.

1 голос
/ 06 декабря 2011

Для этого не было быстрой имплементации. Вместо этого я создал оболочку IEqualityComparer, в которой размещены многочисленные средства сравнения внутренних равенств. Оболочка перезаписала методы 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);
    }
}

Тогда сравнение работает ...

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);
}
...