I'm using a Line class in VisualStudio C# project from a third party (no access to the source) My code is generating hundreds/thousands of line objects containing duplicates and I need to store them in some kind of collection (List, HashSet) for further processing (drawing on the screen). The Line class has StartPoint and EndPoint properties of type Point among others. For the purposes of what I need to do line orientation does not matter and if the start and end points are the same the two Line objects are the same. The class I'm using however behaves differently and two Line objects are considered unique even if they have identical start/end points. (GetHashCode returns different values) Question is - how do I implement a custom IComparer or GetHashCode routines for the third party class in order to be able to use either the HashSet structure or List.Distinct() functionality?
Thanks Ilian and Hasan, that did the trick Quick follow up question if u dont mind: I wasnt sure whether to use a List or a HashSet to hold my data so I tried and timed both. The results show one being orders of magnitude slower than the other. Any insights as to what is going on?
class LineComparer : IEqualityComparer<Line>
{
public bool Equals(Line l1, Line l2)
{
if (l1.EndPoint == l2.EndPoint && l1.StartPoint == l2.StartPoint) return true;
if (l1.EndPoint == l2.StartPoint && l1.StartPoint == l2.EndPoint) return true;
return false;
}
public int GetHashCode(Line line) => line.StartPoint.GetHashCode() ^ line.EndPoint.GetHashCode();
}
and this is my code for HashSet:
var timer = new Stopwatch();
timer.Start();
var result = new HashSet(new LineComparer());
GenerateAndStore20000Lines();
timer.Stop(); Ed.WriteMessage($"\nGenerated {result.Count} lines, time with hashset: {timer.ElapsedMilliseconds}");
return result;
Results: * Time with HashSet: 1302 * Time with HashSet: 1328 * Time with HashSet: 1314 * Time with HashSet: 1311 * Time with HashSet: 1303
code with List:
var timer = new Stopwatch(); timer.Start();
var result = new List();
GenerateAndStore20000Lines();
timer.Stop(); Ed.WriteMessage($"\nGenerated {result.Count} lines, time with List: {timer.ElapsedMilliseconds}");
return result.Distinct(new LineComparer());
Results:
- Generated 20002 lines, time with List: 26
- Generated 20002 lines, time with List: 11
- Generated 20002 lines, time with List: 14
- Generated 20002 lines, time with List: 12
- Generated 20002 lines, time with List: 12
(sorry for the bad formatting, but this interface is driving me crazy ... giving up)