Find properties that are equal in two generic lists

I can't find the oldItem with lambda (x => x.ID.Equals(newItem.ID)) - because it generics. I could provide another parameter like ID and use that to get the value of the property (through reflection) - But it this really the way to go or are there a better way?

private void LogDiff<T>(HashSet<T> newList, HashSet<T> oldList)
{
   Parallel.ForEach(newList, newItem =>
   {
      var oldItem = oldList.FirstOrDefault(x => x.ID.Equals(newItem.ID));
      if (oldItem!= null)
      {
          //Yay i found my item
      });
}
Jon Skeet
people
quotationmark

No, you'd normally provide the ID projection via another parameter:

// Parameters renamed as they're not lists...
private void LogDiff<T, TKey>(HashSet<T> newItems, HashSet<T> oldItems,
                              Func<T, TKey> keySelector)
{
    var comparer = EqualityComparer<TKey>.Default;
    Parallel.ForEach(newItems, newItem =>
    {
        var newKey = keySelector(newItem);
        var oldItem = oldList.FirstOrDefault(x => comparer.Equals(newKey, keySelector(x));
        if (oldItem != null)
        {
            // Use the item
        }
    });
}

However, that's fairly inefficient, compared with just using Join - which can still be performed in parallel:

var query = newItems.AsParallel()
                    .Join(oldItems.AsParallel(), keySelector, keySelector,
                          (n, o) => new { NewItem = n, OldItem = o });

people

See more on this question at Stackoverflow