1

Duplicate Edit: Not a duplicate since all the information that was delivered in the responses is already contained in the question. I was wondering if anyone knew a workaround or at least the expected behavior and that question has not been answered...

(Follow Up question to my last question)

I'm trying to use .GroupJoin() to map a list of keys to another list of keys, except it's also a match if the keys are equal after ignoring capitalization or certain escape-sequences.

For example:

I have a key called "ABCD" in my first list. A list of "Equals" could consist of: {"ABCD", "AbCd", "AB_MINUS_CD", "ab_PLUS_cd"}.

My custom "Equals" checks against a pre-defined list of Escape sequences:

Equals:

public bool Equals(string firstKey, string escapedKey)
{
    int counter = 0;
    while (escapedKey.Count(x => x == '_') >= 2)
    {
        CharacterMaping mapping = Mappings.ElementAt(counter);
        escapedKey = escapedKey.Replace(mapping, "");
    }

    return String.Equals(firstKey, escapedKey, StringComparison.CurrentCultureIgnoreCase);
}

GroupJoin:

IEnumerable<KeyMapping> keyMappings = cleanKeys.GroupJoin(
    escapedKeys,
    c => c,
    e => e,
    (c, result) => new KeyMapping(c, result),
    _keyComparer);

Hoever, I see two problems with this:

  1. To Implement IEqualityComparer<string> I also need to implement GetHashCode(). My assumption right now is that hashing is considered faster than Equals so it first checks for Equality of HashCodes and only if the HashCodes are equal ( = Equality is possible ) it also checks for Equality using Equals(); Since a successful Hash doesn't also automatically mean equality (collisions are possible after all) I might be able to hack around it for my case by simple making GetHashCode() return the same value, regardless of the input.
  2. By definition an IEqualityComparer (or rather any type of equivalence relation needs to be symmetric: a == b => b == a. I am using IEqualityComparer because GroupJoin requires it but I am obviously trying to write a one-directional IEqualityComparer: a == b does not imply b == a. I am, again, just assuming that GroupJoin calls Equals(a, b) with the element of the first list as the first argument but it would be good to know if I have to reverse it :p

Honestly, I am trying to make something work that is just not meant to be that way and I should probably use a different, more manual, loop-based approach but I am really intrigued and wondering if someone can tell me, how this stuff works internally.

Vaethin
  • 316
  • 4
  • 18
  • 2
    `Equals` should be commutative operation, with this request the contract will be broken... – Johnny Apr 08 '19 at 12:53
  • it is very important that you follow the rules when building an equality comparison. You **must** meet the conditions that `A==A` is always true, that `A==B` and `B==A` always have the same value, and that if `A==B` and `B==C` then `A==C`. That is, it must be a reflexive, symmetric and transitive relation, also known as an equivalence relation. If you do not do this, bad things can and will happen. See https://stackoverflow.com/questions/54025578/need-help-understanding-unexpected-behavior-using-linq-join-with-hashsett/54028123#54028123 for an example. – Eric Lippert Apr 08 '19 at 17:12

0 Answers0