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);
78 public static Delegate CreateDelegate (Type type, MethodInfo info)
81 throw new ArgumentNullException (Locale.GetText ("Type is null"));
84 throw new ArgumentNullException (Locale.GetText ("MethodInfo is null"));
86 return CreateDelegate_internal (type, null, info);
90 public static Delegate CreateDelegate (Type type, object target, string method)
93 throw new ArgumentNullException (Locale.GetText ("Type is null"));
96 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
99 throw new ArgumentNullException (Locale.GetText ("method string is null"));
101 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
102 MethodInfo info = target.GetType ().GetMethod (method, flags);
103 return CreateDelegate_internal (type, target, info);
107 public static Delegate CreateDelegate (Type type, Type target, string method)
110 throw new ArgumentNullException (Locale.GetText ("Type is null"));
113 throw new ArgumentNullException (Locale.GetText ("Target type is null"));
116 throw new ArgumentNullException (Locale.GetText ("method string is null"));
118 BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
119 MethodInfo info = target.GetMethod (method, flags);
120 return CreateDelegate_internal (type, null, info);
124 public static Delegate CreateDelegate (Type type, object target, string method, bool ignorecase)
127 throw new ArgumentNullException (Locale.GetText ("Type is null"));
130 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
133 throw new ArgumentNullException (Locale.GetText ("method string is null"));
135 Type target_type = target.GetType ();
136 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase;
137 MethodInfo info = target_type.GetMethod (method, flags);
138 return CreateDelegate_internal (type, target, info);
141 public object DynamicInvoke( object[] args )
143 return DynamicInvokeImpl( args );
146 public virtual object DynamicInvokeImpl( object[] args )
148 if (Method == null) {
149 Type[] mtypes = new Type [args.Length];
150 for (int i = 0; i < args.Length; ++i) {
151 mtypes [i] = args [i].GetType ();
153 method_info = m_target.GetType ().GetMethod (method_name, mtypes);
155 return Method.Invoke( m_target, args );
158 public virtual object Clone()
160 return MemberwiseClone();
163 public override bool Equals (object o)
168 if ( o.GetType() != this.GetType() )
171 Delegate d = (Delegate) o;
172 if ((d.target_type == target_type) &&
173 (d.m_target == m_target) &&
174 (d.method_name == method_name) &&
175 (d.method_ptr == method_ptr))
181 public override int GetHashCode ()
183 return (int)method_ptr;
186 // This is from ISerializable
188 public void GetObjectData (SerializationInfo info, StreamingContext context)
190 // TODO: IMPLEMENT ME
193 public virtual Delegate[] GetInvocationList()
195 return new Delegate[] { this };
199 /// Returns a new MulticastDelegate holding the
200 /// concatenated invocation lists of MulticastDelegates a and b
202 public static Delegate Combine (Delegate a, Delegate b)
212 if (a.GetType () != b.GetType ())
213 throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types"));
215 return a.CombineImpl (b);
219 /// Returns a new MulticastDelegate holding the
220 /// concatenated invocation lists of an Array of MulticastDelegates
222 public static Delegate Combine( Delegate[] delegates )
224 Delegate retval = null;
226 foreach ( Delegate next in delegates )
227 retval = Combine( retval, next );
233 protected virtual Delegate CombineImpl (Delegate d)
235 throw new MulticastNotSupportedException ("");
239 public static Delegate Remove( Delegate source, Delegate value )
241 if ( source == null )
244 return source.RemoveImpl( value );
247 protected virtual Delegate RemoveImpl( Delegate d )
249 if ( this.Equals( d ) )
255 public static bool operator ==( Delegate a, Delegate b )
257 if ((object)a == null) {
258 if ((object)b == null)
262 return a.Equals( b );
265 public static bool operator !=( Delegate a, Delegate b )