Issue #253 resolved

TEnumerableBase<T>.fEqualityComparer should be protected, not private.

Johan Bontes
created an issue

This will allow e.g. the instantiation of a case-insensitive string list.
Right now I cannot change the EqualityComparer because:

GetEqualityComparer is static and the underlying class var is private.
Making the class var fEqualityComparer protected will allow changes in descendant classes without the performance hit of making the property-getter virtual.

See: http://stackoverflow.com/questions/44034797/how-to-create-and-use-a-case-insensitive-iliststring-in-spring4d/44046082#44046082

For more info.

Comments (3)

  1. Stefan Glienke repo owner

    While that might solve the immediate issue the real problem goes a bit deeper. It's caused by the fact that in Spring4D the IndexOf/Contains methods are using the IEqualityComparer and not as in the RTL the IComparer being passed (see below). The IComparer is instance bound and the IEqualityComparer is class bound. I have to check if all places currently using the IEqualityComparer could use IComparer.Compare = 0 as in the RTL.

    That could be a breaking change - I have to investigate if that is acceptable or if it can cause problems.

    P.S. A class property getter cannot be virtual unfortunately.

    Edit: The reason for using IEqualityComparer for Contains and IndexOf is the fact that the default implementation is using the Equals method for objects which can be overridden to give a different result than IComparer.Compare would (for example just checking some Id property).

  2. Stefan Glienke repo owner

    I decided to remove the fEqualityComparer from TEnumerableBase<T> and let TEnumerableBase<T> itself implement IEqualityComparer<T> to be able to pass it to the places that need it. Therefor it implements the Equals and GetHashCode methods (GetHashCode is not being used at any place though). It uses the fComparer if T is not a class and the Equals method when it is a class.

    That should solve this and similar problems where a custom IComparer<T> was not considered when using Contains or IndexOf.

  3. Log in to comment