0

I would like to sort a List<T> by reference. Why? I want to compare several lists and find which elements are unique to a given list. Sorting them first in some canonical fashion and then stepping through all lists simultaneously seems a good way to do this. This essentially means that I need to make aa IComparer<T> that returns a non-zero integer for different references (and is consistent). The order does have to mean anything, but just provide a fixed order for all T for at least the time it takes me to get the job done.

GetHashCode can return the same value for two different objects on a 64-bit system, so that is out as a way to do a comparison.

IntPtr from AddrOfPinnedObject() might work since it has the correct size, but I have to pin the object for the duration of the process.

Making a Dictionary<T, long> where the long is issued first-come first-served is what I'm going with now, but I want to know if there are better options. The hash lookup seems unnecessary.

What is the best way to define ReferenceComparer<T> : IComparer<T> to give me that fixed ordering?

Here is the dictionary implementation:

public class ReferenceComparer<T> : IComparer<T>
{
    private long nextAvailable = 0;
    private readonly Dictionary<T, long> objectToLong = new Dictionary<T, long>(new AsObjectEqualityComparer<T>());

    public int Compare(T x, T y)
    {
        long xLong;
        if (!objectToLong.TryGetValue(x, out xLong))
        {
            xLong = nextAvailable;
            objectToLong[x] = xLong;
            nextAvailable = nextAvailable + 1;
        }

        long yLong;
        if (!objectToLong.TryGetValue(y, out yLong))
        {
            yLong = nextAvailable;
            objectToLong[y] = yLong;
            nextAvailable = nextAvailable + 1;
        }

        return xLong.CompareTo(yLong);
    }
}
Little Endian
  • 784
  • 8
  • 19
  • 1
    The dictionary idea sounds fine, as soon as you add `class` constraint to `T` (or better remove `T` and simply implement `IComparer`), use correctly implemented reference equality comparer in the dictionary and fix the implementation bugs (`xLong` and `yLong` are not set inside the `if` blocks and should be). – Ivan Stoev Sep 24 '16 at 21:36
  • Good catch on not setting `xLong`, `yLong`. – Little Endian Sep 24 '16 at 21:58
  • 1
    I meant, instead of your `ReferenceComparer : IComparer` it would be enough to implement `ReferenceComparer : IComparer`. It could be used for any `List` as soon as `T` is class (reference type). Inside the comparer you would use `Dictionary` with special equality comparer similar to [this](http://referencesource.microsoft.com/#System.Data.Entity/System/Data/Objects/ObjectStateManager.cs,55f103aae513f5b0) – Ivan Stoev Sep 24 '16 at 22:04
  • Yes. I did get that. I think it's a good idea. I assume the `class` constraint is just to make the name meaningful. It works for structs, but what to call it then? – Little Endian Sep 24 '16 at 22:15
  • 1
    You can't compare structs by reference anyway. – Ivan Stoev Sep 24 '16 at 22:20
  • That is what I was implying by my previous comment. – Little Endian Sep 27 '16 at 16:33

0 Answers0