looking at this post: references updated on GC, it seems that the heap could get compacted on a Garbage collection which means that the references would change.
Now if I were to put an object in a Dictionary as a key (assume that the object does not implement GetHashCode/Equals), then the reference would be used to determine it's location within it's internal Hash table. Subsequently on a GC, if the reference changes, and I want to lookup the object how would C# find it?
The dictionary doesn't use the object's location in memory to do book-keeping - it uses the hash code. The hash code of an object doesn't change when the object is moved in memory, even if it doesn't override
GetHashCode(). The details about how that works are very much implementation details, but you can definitely rely on
GetHashCode() returning the same value before and after compaction (assuming the method hasn't been overridden in some bizarre and awful way).
While the implementation details can change over time, this blog post has an interesting (and recent) description. I believe that's still valid in .NET Core (as of April 2018) based on chasing code in the .NET Core CLR GitHub repo - this is a reasonable starting point, as far as I can see.
See more on this question at Stackoverflow