Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / corlib / System / MulticastDelegate.cs
index a87f9ad768c54f5a5fb6772c18cdf372a0ceb30e..fe8be2651186ae32e9e7222d31287f2edd7a701e 100644 (file)
 //
 
 using System.Collections;
+using System.Collections.Generic;
 using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
 
 namespace System
 {
+       [System.Runtime.InteropServices.ComVisible (true)]
+       [Serializable]
+       [StructLayout (LayoutKind.Sequential)]
        public abstract class MulticastDelegate : Delegate
        {
                private MulticastDelegate prev;
@@ -47,8 +52,8 @@ namespace System
                        prev = null;
                }
 
-               protected MulticastDelegate (Type target_type, string method)
-                       : base (target_type, method)
+               protected MulticastDelegate (Type target, string method)
+                       : base (target, method)
                {
                        prev = null;
                }
@@ -67,17 +72,22 @@ namespace System
                        return base.DynamicInvokeImpl (args);
                }
 
+               internal bool HasSingleTarget {
+                       get { return prev == null; }
+               }
                // <remarks>
                //   Equals: two multicast delegates are equal if their base is equal
                //   and their invocations list is equal.
                // </remarks>
-               public sealed override bool Equals (object o)
+               public sealed override bool Equals (object obj)
                {
-                       if (!base.Equals (o))
+                       if (!base.Equals (obj))
                                return false;
 
-                       MulticastDelegate d = (MulticastDelegate) o;
-
+                       MulticastDelegate d = obj as MulticastDelegate;
+                       if (d == null)
+                               return false;
+                       
                        if (this.prev == null) {
                                if (d.prev == null)
                                        return true;
@@ -114,7 +124,7 @@ namespace System
                                return new Delegate [1] { other };
                        }
 
-                       ArrayList list = new ArrayList ();
+                       var list = new List<Delegate> ();
                        for (; d != null; d = d.kpm_next) {
                                MulticastDelegate other = (MulticastDelegate) d.Clone ();
                                other.prev = null;
@@ -122,7 +132,7 @@ namespace System
                                list.Add (other);
                        }
 
-                       return (Delegate []) list.ToArray (typeof (Delegate));
+                       return list.ToArray ();
                }
 
                // <summary>
@@ -136,9 +146,10 @@ namespace System
                        MulticastDelegate combined, orig, clone;
 
                        if (this.GetType() != follow.GetType ())
-                               throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types."));
+                               throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types. First is {0} second is {1}.", this.GetType ().FullName, follow.GetType ().FullName));
 
                        combined = (MulticastDelegate)follow.Clone ();
+                       combined.SetMulticastInvoke ();
 
                        for (clone = combined, orig = ((MulticastDelegate)follow).prev; orig != null; orig = orig.prev) {
                                
@@ -253,19 +264,20 @@ namespace System
                        return retval;
                }
 
-               public static bool operator == (MulticastDelegate a, MulticastDelegate b)
+               public static bool operator == (MulticastDelegate d1, MulticastDelegate d2)
                {
-                       if ((object)a == null) {
-                               if ((object)b == null)
-                                       return true;
-                               return false;
-                       }
-                       return a.Equals (b);
+                       if (d1 == null)
+                               return d2 == null;
+                               
+                       return d1.Equals (d2);
                }
                
-               public static bool operator != (MulticastDelegate a, MulticastDelegate b)
+               public static bool operator != (MulticastDelegate d1, MulticastDelegate d2)
                {
-                       return !(a == b);
+                       if (d1 == null)
+                               return d2 != null;
+                       
+                       return !d1.Equals (d2);
                }
        }
 }