Given two lists of different types, is it possible to make those types convertible between or comparable to each other (eg with a TypeConverter or similar) so that a LINQ query can compare them? I've seen other similar questions on SO but nothing that points to making the types convertible between each other to solve the problem.
Collection Types:
public class Data
{
public int ID { get; set; }
}
public class ViewModel
{
private Data _data;
public ViewModel(Data data)
{
_data = data;
}
}
Desired usage:
public void DoMerge(ObservableCollection<ViewModel> destination, IEnumerable<Data> data)
{
// 1. Find items in data that don't already exist in destination
var newData = destination.Except(data);
// ...
}
It would seem logical that since I know how to compare an instance of ViewModel to an instance of Data I should be able to provide some comparison logic that LINQ would then use for queries like .Except(). Is this possible?
If you use this :
You have to project 'data' to same type contained in 'destination', but using the code below you could get rid of this limitation :
Some may argue that's memory inefficient due to the use of an HashSet. But actually the Enumerable.Except method of the framework is doing the same with a similar internal class called 'Set' (I took a look by decompiling).
Your best bet is to provide a projection from
Data
toViewModel
so that you can saywhere
f
mapsData
toViewModel
. You will need aIEqualityComparer<Data>
too.I assume that providing a projection from
Data
toViewModel
is problematic, so I'm offering another solution in addition to Jason's.Except uses a hash set (if I recall correctly), so you can get similar performance by creating your own hashset. I'm also assuming that you are identifying
Data
objects as equal when theirIDs
are equal.You might have another use for a collection of "oldData" elsewhere in the method, in which case, you would want to do this instead. Either implement
IEquatable<Data>
on your data class, or create a customIEqualityComparer<Data>
for the hash set: