5 // Miguel de Icaza (miguel@ximian.com)
6 // Daniel Stodden (stodden@in.tum.de)
7 // Dietmar Maurer (dietmar@ximian.com)
9 // (C) Ximian, Inc. http://www.ximian.com
13 using System.Globalization;
14 using System.Reflection;
15 using System.Runtime.Serialization;
16 using System.Runtime.CompilerServices;
22 public abstract class Delegate : ICloneable, ISerializable {
23 protected Type target_type;
24 protected object m_target;
25 protected string method_name;
26 protected IntPtr method_ptr;
27 protected IntPtr delegate_trampoline;
28 protected MethodInfo method_info;
30 protected Delegate (object target, string method)
33 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
36 throw new ArgumentNullException (Locale.GetText ("method name is null"));
38 this.target_type = null;
39 this.method_ptr = IntPtr.Zero;
40 this.m_target = target;
41 this.method_name = method;
44 protected Delegate (Type target_type, string method)
47 throw new ArgumentNullException (Locale.GetText ("Target type is null"));
50 throw new ArgumentNullException (Locale.GetText ("method string is null"));
52 this.target_type = target_type;
53 this.method_ptr = IntPtr.Zero;
55 this.method_name = method;
58 public MethodInfo Method {
64 public object Target {
74 [MethodImplAttribute(MethodImplOptions.InternalCall)]
75 internal static extern Delegate CreateDelegate_internal (Type type, object target, MethodInfo info);
77 public static Delegate CreateDelegate (Type type, MethodInfo info)
80 throw new ArgumentNullException (Locale.GetText ("Type is null"));
83 throw new ArgumentNullException (Locale.GetText ("MethodInfo is null"));
85 return CreateDelegate_internal (type, null, info);
88 public static Delegate CreateDelegate (Type type, object target, string method)
91 throw new ArgumentNullException (Locale.GetText ("Type is null"));
94 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
97 throw new ArgumentNullException (Locale.GetText ("method string is null"));
99 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
100 MethodInfo info = target.GetType ().GetMethod (method, flags);
101 return CreateDelegate_internal (type, target, info);
104 public static Delegate CreateDelegate (Type type, Type target, string method)
107 throw new ArgumentNullException (Locale.GetText ("Type is null"));
110 throw new ArgumentNullException (Locale.GetText ("Target type is null"));
113 throw new ArgumentNullException (Locale.GetText ("method string is null"));
115 BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
116 MethodInfo info = target.GetMethod (method, flags);
117 return CreateDelegate_internal (type, null, info);
120 public static Delegate CreateDelegate (Type type, object target, string method, bool ignorecase)
123 throw new ArgumentNullException (Locale.GetText ("Type is null"));
126 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
129 throw new ArgumentNullException (Locale.GetText ("method string is null"));
131 Type target_type = target.GetType ();
132 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase;
133 MethodInfo info = target_type.GetMethod (method, flags);
134 return CreateDelegate_internal (type, target, info);
137 public object DynamicInvoke( object[] args )
139 return DynamicInvokeImpl( args );
142 public virtual object DynamicInvokeImpl( object[] args )
144 if (Method == null) {
145 Type[] mtypes = new Type [args.Length];
146 for (int i = 0; i < args.Length; ++i) {
147 mtypes [i] = args [i].GetType ();
149 method_info = m_target.GetType ().GetMethod (method_name, mtypes);
151 return Method.Invoke( m_target, args );
154 public virtual object Clone()
156 return MemberwiseClone();
159 public override bool Equals (object o)
164 if ( o.GetType() != this.GetType() )
167 Delegate d = (Delegate) o;
168 if ((d.target_type == target_type) &&
169 (d.m_target == m_target) &&
170 (d.method_name == method_name) &&
171 (d.method_ptr == method_ptr))
177 public override int GetHashCode ()
179 return (int)method_ptr;
182 // This is from ISerializable
184 public void GetObjectData (SerializationInfo info, StreamingContext context)
186 // TODO: IMPLEMENT ME
189 public virtual Delegate[] GetInvocationList()
191 return new Delegate[] { this };
195 /// Returns a new MulticastDelegate holding the
196 /// concatenated invocation lists of MulticastDelegates a and b
198 public static Delegate Combine (Delegate a, Delegate b)
208 if (a.GetType () != b.GetType ())
209 throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types"));
211 return a.CombineImpl (b);
215 /// Returns a new MulticastDelegate holding the
216 /// concatenated invocation lists of an Array of MulticastDelegates
218 public static Delegate Combine( Delegate[] delegates )
220 Delegate retval = null;
222 foreach ( Delegate next in delegates )
223 retval = Combine( retval, next );
229 protected virtual Delegate CombineImpl (Delegate d)
231 throw new MulticastNotSupportedException ("");
235 public static Delegate Remove( Delegate source, Delegate value )
237 if ( source == null )
240 return source.RemoveImpl( value );
243 protected virtual Delegate RemoveImpl( Delegate d )
245 if ( this.Equals( d ) )
251 public static bool operator ==( Delegate a, Delegate b )
253 if ((object)a == null) {
254 if ((object)b == null)
258 return a.Equals( b );
261 public static bool operator !=( Delegate a, Delegate b )