2002-03-14 Dietmar Maurer <dietmar@ximian.com>
[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 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 //
10 // TODO:  Mucho left to implement
11 //
12
13 using System;
14 using System.Globalization;
15 using System.Reflection;
16 using System.Runtime.Serialization;
17
18 namespace System {
19
20         [MonoTODO]
21         public abstract class Delegate : ICloneable, ISerializable {
22                 protected Type target_type;
23                 protected object m_target;
24                 protected string method_name;
25                 protected IntPtr method_ptr;
26                 protected MethodInfo method_info;
27
28                 protected Delegate (object target, string method)
29                 {
30                         if (target == null)
31                                 throw new ArgumentNullException (Locale.GetText ("Target object is null"));
32
33                         if (method == null)
34                                 throw new ArgumentNullException (Locale.GetText ("method name is null"));
35
36                         this.target_type = null;
37                         this.method_ptr = IntPtr.Zero;
38                         this.m_target = target;
39                         this.method_name = method;
40                 }
41
42                 protected Delegate (Type target_type, string method)
43                 {
44                         if (m_target == null)
45                                 throw new ArgumentNullException (Locale.GetText ("Target type is null"));
46
47                         if (method == null)
48                                 throw new ArgumentNullException (Locale.GetText ("method string is null"));
49
50                         this.target_type = target_type;
51                         this.method_ptr = IntPtr.Zero;
52                         this.m_target = null;
53                         this.method_name = method;
54                 }
55
56                 public MethodInfo Method {
57                         get {
58                                 return method_info;
59                         }
60                 }
61
62                 public object Target {
63                         get {
64                                 return m_target;
65                         }
66                 }
67
68                 //
69                 // Methods
70                 //
71
72                 public object DynamicInvoke( object[] args )
73                 {
74                         return DynamicInvokeImpl( args );
75                 }
76
77                 public virtual object DynamicInvokeImpl( object[] args )
78                 {
79                         return Method.Invoke( m_target, args );
80                 }
81
82                 public virtual object Clone()
83                 {
84                         return MemberwiseClone();
85                 }
86
87                 public override bool Equals (object o)
88                 {
89                         if ( o == null )
90                                 return false;
91                         
92                         if ( o.GetType() != this.GetType() )
93                                 return false;
94
95                         Delegate d = (Delegate) o;
96                         if ((d.target_type == target_type) &&
97                             (d.m_target == m_target) &&
98                             (d.method_name == method_name) &&
99                             (d.method_ptr == method_ptr))
100                                 return true;
101
102                         return false;
103                 }
104
105                 public override int GetHashCode ()
106                 {
107                         return (int)method_ptr;
108                 }
109
110                 // This is from ISerializable
111                 [MonoTODO]
112                 public void GetObjectData (SerializationInfo info, StreamingContext context)
113                 {
114                         // TODO: IMPLEMENT ME
115                 }
116
117                 public virtual Delegate[] GetInvocationList()
118                 {
119                         return new Delegate[] { this };
120                 }
121
122                 /// <symmary>
123                 ///   Returns a new MulticastDelegate holding the
124                 ///   concatenated invocation lists of MulticastDelegates a and b
125                 /// </symmary>
126                 public static Delegate Combine (Delegate a, Delegate b)
127                 {
128                         if (a == null){
129                                 if (b == null)
130                                         return null;
131                                 return b;
132                         } else 
133                                 if (b == null)
134                                         return a;
135
136                         if (a.GetType () != b.GetType ())
137                                 throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types"));
138                         
139                         return a.CombineImpl (b);
140                 }
141
142                 /// <symmary>
143                 ///   Returns a new MulticastDelegate holding the
144                 ///   concatenated invocation lists of an Array of MulticastDelegates
145                 /// </symmary>
146                 public static Delegate Combine( Delegate[] delegates )
147                 {
148                         Delegate retval = null;
149
150                         foreach ( Delegate next in delegates ) {
151                                 retval = Combine( retval, next );
152                         }
153
154                         return retval;
155                 }
156
157
158                 protected virtual Delegate CombineImpl (Delegate d)
159                 {
160                         throw new MulticastNotSupportedException ("");
161                 }
162                 
163                 [MonoTODO]
164                 public static Delegate Remove( Delegate source, Delegate value) {
165                         if ( source == null )
166                                 return null;
167                                 
168                         if ( value == null )
169                                 return source;
170
171                         throw new NotImplementedException ();
172                 }
173
174                 [MonoTODO]
175                 protected virtual Delegate RemoveImpl(Delegate d)
176                 {
177                         throw new NotImplementedException();
178                 }
179
180                 public static bool operator ==( Delegate a, Delegate b )
181                 {
182                         if ((object)a == null) {
183                                 if ((object)b == null)
184                                         return true;
185                                 return false;
186                         }
187                         return a.Equals( b );
188                 }
189
190                 public static bool operator !=( Delegate a, Delegate b )
191                 {
192                         return !(a == b);
193                 }
194         }
195 }