Implementing IEqualityComparer in C# .NET MVC

醉酒当歌 提交于 2019-12-12 01:48:45

问题


I've implemented a custom comparer like following:

public class CustomComparer : IEqualityComparer<StoredEmails>
{
    public static readonly IEqualityComparer<StoredEmails> Instance = new CustomComparer();

    public bool Equals(StoredEmails x, StoredEmails y)
    {
        return x.Email == y.Email;
    }

    public int GetHashCode(StoredEmails x)
    {
        return x.Email.GetHashCode();
    }
}

This one basically compares two lists (two equally same typed lists) and adds ONLY MISSING emails from that list to the new one and then I insert those emails to my database...

Usage example:

var oldList = new List<StoredEmails>(); // lets suppose it has 5000 emails or something like that, just for example's sake...

var ListDoAdd = prepared.Except(oldList, CustomComparer.Instance).ToList();

Where "prepared" list is the new one which is compared to the old list..

Now I'd like to implement this as well , just for different class and different criteria rules:

- Items class

Where I have two identically typed lists (old and new list) of items which contains following data:

- ItemID
- QuantitySold

Usage example and desired outcome:

var oldItems= new List<Items>(); // suppose it has 5000 items inside...

var newItems = new List<Items>(); // suppose it has 15000 items...

var thirdList = newItems .Except(oldItems, CustomComparer.Instance).ToList();

Where the criteria for the items to be added to thirdList list are following:

  • if ItemID in newList is not present in oldList
  • If both ItemID's are present in both list but their QuantitySold properties are not equal...

Can I implement this using one IEqualityComparer? Can someone help me out?

@CodingYoshi, will something like this do:

public static readonly IEqualityComparer<Items> Instance = new ItemsComparer();

public bool Equals(Items x, Items y)
{
    if (x.ItemId != y.ItemId || x.QuantitySoldTotal != y.QuantitySoldTotal)
        return true;
    return false;
}

public int GetHashCode(Items x)
{
    return x.ItemId.GetHashCode();
}

回答1:


I wrote an extension method that does the desired behavior for you.

If the new item is not in the old items list, it will be added to the result list. If the item was modified, it will also be added to the result list.

Code:

public static class CollectionExtensions
{
    public static IList<T> GetNewOrModifiedItems<T, TKey>(
        this IList<T> newItems,
        IList<T> oldItems,
        Func<T, TKey> getKey,
        IEqualityComparer<T> comparer)
    {
        oldItems = oldItems ?? new List<T>();
        newItems = newItems ?? new List<T>();

        var oldItemsDictionary = oldItems.ToDictionary(getKey);
        var results = new List<T>();

        foreach (var item in newItems)
        {
            if (!oldItemsDictionary.ContainsKey(getKey(item)) ||
                !comparer.Equals(item, oldItemsDictionary[getKey(item)]))
            {
                results.Add(item);
            }
        }

        return results;
    }
}

Usage:

var oldItems = new List<Items>(); // suppose it has 5000 items...
var newItems = new List<Items>(); // suppose it has 15000 items...

var thirdList = newItems.GetNewOrModifiedItems(
    oldItems,
    x => x.ItemId,
    CustomComparer.Instance);


来源:https://stackoverflow.com/questions/43596909/implementing-iequalitycomparer-in-c-sharp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!