Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic list comparator doesn't work with list<keyvaluePair>

I created a class to compare to generic list by one property.

public class ListComparator<TOriginal,TNew>
{

    public ListComparator(IEnumerable<TOriginal> iOriginalList, Func<TOriginal, IComparable> iOriginalProperty, IEnumerable<TNew> iNewList, Func<TNew, IComparable> iNewProperty)
    {
        if (iOriginalProperty == null ||
            iNewProperty == null) { throw new ArgumentNullException(); };

            if (iOriginalList.IsNullOrEmpty() )
            {
                NewList = (iNewList != null) ? iNewList.ToList() : null;
                return;
            }

            if (iNewList.IsNullOrEmpty())
            {
                RemovedList = (iOriginalList != null) ? iOriginalList.ToList() : null;
                return;
            }


            NewList = (from tnew in iNewList.ToList()
                       join toriginal in iOriginalList.ToList()
                       on iNewProperty(tnew)
                       equals iOriginalProperty(toriginal) into gj
                       from item in gj.DefaultIfEmpty()
                       where item == null
                       select tnew).ToList();

            CommunList = (from tnew in iNewList.ToList()
                          join toriginal in iOriginalList.ToList()
                          on iNewProperty(tnew)
                          equals iOriginalProperty(toriginal) into gj
                          from item in gj.DefaultIfEmpty()
                          where item != null
                          select tnew).ToList();

            CommunPairList = (from tnew in iNewList.ToList()
                              join toriginal in iOriginalList.ToList()
                              on iNewProperty(tnew)
                              equals iOriginalProperty(toriginal) into gj
                              from item in gj.DefaultIfEmpty()
                              where item != null
                              select new KeyValuePair<TOriginal, TNew>(item, tnew)).ToList();

            RemovedList = (from toriginal in iOriginalList.ToList()
                           join tnew in iNewList.ToList()
                           on iOriginalProperty(toriginal)
                           equals iNewProperty(tnew) into gj
                           from item in gj.DefaultIfEmpty()
                           where item == null
                           select toriginal).ToList();
            return;

    }

    #region PROPRIETES

    public List<TNew> NewList { get; private set; }
    public List<TOriginal> RemovedList { get; private set; }
    public List<TNew> CommunList { get; private set; }
    /// <summary>
    /// Obtient la liste de pair avec l'original en key et le nouveau en value
    /// </summary>
    public List<KeyValuePair<TOriginal,TNew>> CommunPairList { get; private set; }

    #endregion

I use it like this:

List<Tuple<string, string>> list1 = new List<Tuple<string, string>>();
            List<Tuple<string, string>> list2 = new List<Tuple<string, string>>();

            list1.Add(new Tuple<string, string>("AA", "zefzef"));
            list1.Add(new Tuple<string, string>("A1", "iulyu"));

            list2.Add(new Tuple<string, string>("Abb", "szefez"));
            list2.Add(new Tuple<string, string>("A1", "zevzez"));

            ListComparator<Tuple<string, string>, Tuple<string, string>> comp = new ListComparator<Tuple<string, string>, Tuple<string, string>>(list1, x => x.Item1, list2, a => a.Item1);

Output: 1 commun 1 new 1 removed

My problem is when I replace tuple by keyValuePair

List<KeyValuePair<string, string>> list1 = new List<KeyValuePair<string, string>>();
            List<KeyValuePair<string, string>> list2 = new List<KeyValuePair<string, string>>();

            list1.Add(new KeyValuePair<string, string>("AA", "zefzef"));
            list1.Add(new KeyValuePair<string, string>("A1", "iulyu"));

            list2.Add(new KeyValuePair<string, string>("Abb", "szefez"));
            list2.Add(new KeyValuePair<string, string>("A1", "zevzez"));


            ListComparator<KeyValuePair<string, string>, KeyValuePair<string, string>> comp = new ListComparator<KeyValuePair<string, string>, KeyValuePair<string, string>>(list1, x => x.Key, list2, a => a.Key);

I get the input : commun 2

I don't understand .... why ? How to correct it ? Thanks

like image 540
Julian50 Avatar asked Dec 15 '25 13:12

Julian50


1 Answers

The reason for this is that KeyValuePair is a struct rather than a class- meaning a value rather than reference type. This means that default(KeyValuePair<string,string>) isn't null, so the lines where item == null and where item != null don't work as expected

like image 123
Ben Aaronson Avatar answered Dec 17 '25 02:12

Ben Aaronson