Question on WeakReference<T> behavior

Mar 12, 2009 at 2:52 PM
Edited Mar 12, 2009 at 2:54 PM
Preface: Yes I know this is an internal class in a Microsoft.Internal namespace. 

In looking at the code and tests for the class WeakReference<T> there is some behavior in the Equals method that I don't understand.  Here is the method in question:

       public override bool Equals(object obj)
        {
            WeakReference<T> weakRef = obj as WeakReference<T>;

            if (weakRef == null)
            {
                return false;
            }

            object target1 = this.Target;
            object target2 = weakRef.Target;

            if (target1 == null || target2 == null)
            {
                return base.Equals(weakRef);
            }

            return target1.Equals(target2);
        }

If either of the targets is null the comparison is done using the base.Equals method, which means that if the object is being compared to itself, the result will be true and will otherwise be false. Doing this however means that the method changes mid-stream what the meaning of "equals" means.  For the case where both objects are WeakReference<T> equality becomes - "Compare target instances unless either target is null in which case compare WeakReference<T> instances" which moves from a kind of value equality to a reference equality based the null/not null value of the field Target. 

What I don't understand is why this particular equality behavior?  WeakReference<T> is only used in WeakReferenceCollection<T> (which does not implement ICollection<T> :( ) and WeakReferenceCollection<T> does have seem to make use of this particular equality behavior. 

Is there some design reason for this particular approach that some consumer needs?
Developer
Mar 26, 2009 at 6:15 PM
Edited Mar 26, 2009 at 6:16 PM
You are correct this method is not used any longer and is likely in fact broken. It did get used by our implementation of ConditionalWeakTable which used it as the key into a dictionary but we ended up creating a custom version for that. We should remove it.

Thanks,
Wes