removed TODO attribute
[mono.git] / mcs / class / corlib / System / Delegate.cs
1 //
2 // System.Delegate.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Daniel Stodden (stodden@in.tum.de)
7 //   Dietmar Maurer (dietmar@ximian.com)
8 //
9 // (C) Ximian, Inc.  http://www.ximian.com
10 //
11
12 using System;
13 using System.Globalization;
14 using System.Reflection;
15 using System.Runtime.Serialization;
16 using System.Runtime.CompilerServices;
17
18
19 namespace System {
20
21         [MonoTODO]
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;
29
30                 protected Delegate (object target, string method)
31                 {
32                         if (target == null)
33                                 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
34
35                         if (method == null)
36                                 throw new ArgumentNullException (Locale.GetText ("method name is null"));
37
38                         this.target_type = null;
39                         this.method_ptr = IntPtr.Zero;
40                         this.m_target = target;
41                         this.method_name = method;
42                 }
43
44                 protected Delegate (Type target_type, string method)
45                 {
46                         if (m_target == null)
47                                 throw new ArgumentNullException (Locale.GetText ("Target type is null"));
48
49                         if (method == null)
50                                 throw new ArgumentNullException (Locale.GetText ("method string is null"));
51
52                         this.target_type = target_type;
53                         this.method_ptr = IntPtr.Zero;
54                         this.m_target = null;
55                         this.method_name = method;
56                 }
57
58                 public MethodInfo Method {
59                         get {
60                                 return method_info;
61                         }
62                 }
63
64                 public object Target {
65                         get {
66                                 return m_target;
67                         }
68                 }
69
70                 //
71                 // Methods
72                 //
73
74                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
75                 internal static extern Delegate CreateDelegate_internal (Type type, object target, MethodInfo info);
76
77                 public static Delegate CreateDelegate (Type type, MethodInfo info)
78                 {
79                         if (type == null)
80                                 throw new ArgumentNullException (Locale.GetText ("Type is null"));
81
82                         if (info == null)
83                                 throw new ArgumentNullException (Locale.GetText ("MethodInfo is null"));
84
85                         return CreateDelegate_internal (type, null, info);
86                 }
87                 
88                 public static Delegate CreateDelegate (Type type, object target, string method)
89                 {
90                         if (type == null)
91                                 throw new ArgumentNullException (Locale.GetText ("Type is null"));
92
93                         if (target == null)
94                                 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
95
96                         if (method == null)
97                                 throw new ArgumentNullException (Locale.GetText ("method string is null"));
98
99                         BindingFlags flags =  BindingFlags.Public | BindingFlags.Instance;
100                         MethodInfo info = target.GetType ().GetMethod (method, flags);
101                         return CreateDelegate_internal (type, target, info);
102                 }
103
104                 public static Delegate CreateDelegate (Type type, Type target, string method)
105                 {
106                         if (type == null)
107                                 throw new ArgumentNullException (Locale.GetText ("Type is null"));
108
109                         if (target == null)
110                                 throw new ArgumentNullException (Locale.GetText ("Target type is null"));
111
112                         if (method == null)
113                                 throw new ArgumentNullException (Locale.GetText ("method string is null"));
114
115                         BindingFlags flags =  BindingFlags.Public | BindingFlags.Static;
116                         MethodInfo info = target.GetMethod (method, flags);
117                         return CreateDelegate_internal (type, null, info);
118                 }
119
120                 public static Delegate CreateDelegate (Type type, object target, string method, bool ignorecase)
121                 {
122                         if (type == null)
123                                 throw new ArgumentNullException (Locale.GetText ("Type is null"));
124
125                         if (target == null)
126                                 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
127
128                         if (method == null)
129                                 throw new ArgumentNullException (Locale.GetText ("method string is null"));
130                         
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);                    
135                 }
136
137                 public object DynamicInvoke( object[] args )
138                 {
139                         return DynamicInvokeImpl( args );
140                 }
141
142                 public virtual object DynamicInvokeImpl( object[] args )
143                 {
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 ();
148                         }
149                                 method_info = m_target.GetType ().GetMethod (method_name, mtypes);
150                         }
151                         return Method.Invoke( m_target, args );
152                 }
153
154                 public virtual object Clone()
155                 {
156                         return MemberwiseClone();
157                 }
158
159                 public override bool Equals (object o)
160                 {
161                         if ( o == null )
162                                 return false;
163                         
164                         if ( o.GetType() != this.GetType() )
165                                 return false;
166
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))
172                                 return true;
173
174                         return false;
175                 }
176
177                 public override int GetHashCode ()
178                 {
179                         return (int)method_ptr;
180                 }
181
182                 // This is from ISerializable
183                 [MonoTODO]
184                 public void GetObjectData (SerializationInfo info, StreamingContext context)
185                 {
186                         // TODO: IMPLEMENT ME
187                 }
188
189                 public virtual Delegate[] GetInvocationList()
190                 {
191                         return new Delegate[] { this };
192                 }
193
194                 /// <symmary>
195                 ///   Returns a new MulticastDelegate holding the
196                 ///   concatenated invocation lists of MulticastDelegates a and b
197                 /// </symmary>
198                 public static Delegate Combine (Delegate a, Delegate b)
199                 {
200                         if (a == null){
201                                 if (b == null)
202                                         return null;
203                                 return b;
204                         } else 
205                                 if (b == null)
206                                         return a;
207
208                         if (a.GetType () != b.GetType ())
209                                 throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types"));
210                         
211                         return a.CombineImpl (b);
212                 }
213
214                 /// <symmary>
215                 ///   Returns a new MulticastDelegate holding the
216                 ///   concatenated invocation lists of an Array of MulticastDelegates
217                 /// </symmary>
218                 public static Delegate Combine( Delegate[] delegates )
219                 {
220                         Delegate retval = null;
221
222                         foreach ( Delegate next in delegates )
223                                 retval = Combine( retval, next );
224
225                         return retval;
226                 }
227
228
229                 protected virtual Delegate CombineImpl (Delegate d)
230                 {
231                         throw new MulticastNotSupportedException ("");
232                 }
233                 
234                 
235                 public static Delegate Remove( Delegate source, Delegate value ) 
236                 {
237                         if ( source == null )
238                                 return null;
239                                 
240                         return source.RemoveImpl( value );
241                 }
242
243                 protected virtual Delegate RemoveImpl( Delegate d )
244                 {
245                         if ( this.Equals( d ) )
246                                 return null;
247                        
248                         return this;
249                 }
250
251                 public static bool operator ==( Delegate a, Delegate b )
252                 {
253                         if ((object)a == null) {
254                                 if ((object)b == null)
255                                         return true;
256                                 return false;
257                         }
258                         return a.Equals( b );
259                 }
260
261                 public static bool operator !=( Delegate a, Delegate b )
262                 {
263                         return !(a == b);
264                 }
265         }
266 }