public sealed override bool Equals(object obj) { if ((obj == null) || !Delegate.InternalEqualTypes(this, obj)) { return(false); } MulticastDelegate d = obj as MulticastDelegate; if (d == null) { return(false); } if (this._invocationCount != IntPtr.Zero) { if (this._invocationList == null) { if (!this.IsUnmanagedFunctionPtr()) { return(base.Equals(obj)); } if (!d.IsUnmanagedFunctionPtr()) { return(false); } if (base._methodPtr != d._methodPtr) { return(false); } if (base.GetUnmanagedCallSite() != d.GetUnmanagedCallSite()) { return(false); } return(true); } if (this._invocationList is Delegate) { return(this._invocationList.Equals(obj)); } return(this.InvocationListEquals(d)); } if (this._invocationList != null) { if (!this._invocationList.Equals(d._invocationList)) { return(false); } return(base.Equals(d)); } if ((d._invocationList == null) && !(d._invocationCount != IntPtr.Zero)) { return(base.Equals(d)); } return((d._invocationList is Delegate) && (d._invocationList as Delegate).Equals(this)); }
// equals returns true IIF the delegate is not null and has the // same target, method and invocation list as this object public override sealed bool Equals(Object obj) { if (obj == null || !InternalEqualTypes(this, obj)) { return(false); } MulticastDelegate d = obj as MulticastDelegate; if (d == null) { return(false); } if (_invocationCount != (IntPtr)0) { // there are 4 kind of delegate kinds that fall into this bucket // 1- Multicast (_invocationList is Object[]) // 2- Secure (_invocationList is Delegate) // 3- Unmanaged FntPtr (_invocationList == null) // 4- Open virtual (_invocationCount == MethodDesc of target) if (_invocationList == null) { if (IsUnmanagedFunctionPtr()) { if (!d.IsUnmanagedFunctionPtr()) { return(false); } if (_methodPtr != d._methodPtr) { return(false); } if (GetUnmanagedCallSite() != d.GetUnmanagedCallSite()) { return(false); } return(true); } return(base.Equals(obj)); } else { if ((_invocationList as Delegate) != null) { // this is a secure delegate so we need to unwrap and check the inner one return(_invocationList.Equals(obj)); } else { BCLDebug.Assert((_invocationList as Object[]) != null, "empty invocation list on multicast delegate"); return(InvocationListEquals(d)); } } } else { // among the several kind of delegates falling into this bucket one has got a non // empty _invocationList (open static with special sig) // to be equals we need to check that _invocationList matches (both null is fine) // and call the base.Equals() if (_invocationList != null) { if (!_invocationList.Equals(d._invocationList)) { return(false); } return(base.Equals(d)); } // now we know 'this' is not a special one, so we can work out what the other is if (d._invocationList != null || d._invocationCount != (IntPtr)0) { if ((d._invocationList as Delegate) != null) { // this is a secure delegate so we need to unwrap and check the inner one return((d._invocationList as Delegate).Equals(this)); } return(false); } // now we can call on the base return(base.Equals(d)); } }