microsoft / referencesource

Source from the Microsoft .NET Reference Source that represent a subset of the .NET Framework
https://referencesource.microsoft.com/
MIT License
3.18k stars 1.28k forks source link

When use customer comparer on Intersect if hited will not continue. #36

Closed toiiggww closed 5 years ago

toiiggww commented 7 years ago

https://github.com/Microsoft/referencesource/blob/7de0d30c7c5ef56ab60fee41fcdb50005d24979a/System.Core/System/Linq/Enumerable.cs#L763 class ClazzA { public int Int { get; set; } public char Char { get; set; } public string String { get; set; } } class ClazzAComparer : IEnumerable { public bool Equals(ClazzA x, ClazzA y) { return x != null & y != null ? ( x.String == y.String & x.Int == y.Int ) : x == null & y == null; } public int GetHashCode(ClazzA obj) { return obj.String.GetHashCode(); } } class MainClazz { static List las = new List{ new ClazzA { Int = 0, Char = 'a', String = 'str'}, new ClazzA { Int = 1, Char = 'a', String = 'str'}, new ClazzA { Int = 0, Char = 'b', String = 'str'}, new ClazzA { Int = 1, Char = 'b', String = 'str'} }; void Main( ) { ClazzAComparer cmp = new ClazzAComparer(); var ld = las.Distinct(cmp); // will be las[0] and las[1] var li = las.Intersect(ld, cmp); // will be only las[0] and las[1] but I wish all of las foreach (var i in li) { Console.WriteLine($"int {i.Int,-3}, char {i.Char,-3}, string {i.String,8}"); } } }

full demo project at https://github.com/toiiggww/IEnumerableIntersect

svick commented 7 years ago

The documentation says:

When the object returned by this method is enumerated, Intersect yields distinct elements occurring in both sequences

Since it's the comparer that decides which elements are distinct, I think the behavior you see is correct.

To get the behavior you want, you can combine Where and Contains:

var li = las.Where(l => ld.Contains(l, cmp));

(Though this approach is inefficient. If that matters to you, you might want to turn ld into a HashSet.)

toiiggww commented 7 years ago

Thanks for your comment

terrajobst commented 5 years ago

This repo only tracks infrastructure issues regarding the following items:

For issues regarding functionality, please use the following resources: