2002-08-21 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mcs / class / corlib / System / Delegate.cs
index 1d04aa97be042998a859900beca60dad74c8654d..8320f380cd9c9c7e641a818c9f58ee98be40faad 100644 (file)
@@ -4,16 +4,17 @@
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
 //   Daniel Stodden (stodden@in.tum.de)
+//   Dietmar Maurer (dietmar@ximian.com)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
 //
-// TODO:  Mucho left to implement
-//
 
 using System;
 using System.Globalization;
 using System.Reflection;
 using System.Runtime.Serialization;
+using System.Runtime.CompilerServices;
+
 
 namespace System {
 
@@ -23,6 +24,7 @@ namespace System {
                protected object m_target;
                protected string method_name;
                protected IntPtr method_ptr;
+               protected IntPtr delegate_trampoline;
                protected MethodInfo method_info;
 
                protected Delegate (object target, string method)
@@ -69,6 +71,69 @@ namespace System {
                // Methods
                //
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               internal static extern Delegate CreateDelegate_internal (Type type, object target, MethodInfo info);
+
+               public static Delegate CreateDelegate (Type type, MethodInfo info)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException (Locale.GetText ("Type is null"));
+
+                       if (info == null)
+                               throw new ArgumentNullException (Locale.GetText ("MethodInfo is null"));
+
+                       return CreateDelegate_internal (type, null, info);
+               }
+               
+               public static Delegate CreateDelegate (Type type, object target, string method)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException (Locale.GetText ("Type is null"));
+
+                       if (target == null)
+                               throw new ArgumentNullException (Locale.GetText ("Target object is null"));
+
+                       if (method == null)
+                               throw new ArgumentNullException (Locale.GetText ("method string is null"));
+
+                       BindingFlags flags =  BindingFlags.Public | BindingFlags.Instance;
+                       MethodInfo info = target.GetType ().GetMethod (method, flags);
+                       return CreateDelegate_internal (type, target, info);
+               }
+
+               public static Delegate CreateDelegate (Type type, Type target, string method)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException (Locale.GetText ("Type is null"));
+
+                       if (target == null)
+                               throw new ArgumentNullException (Locale.GetText ("Target type is null"));
+
+                       if (method == null)
+                               throw new ArgumentNullException (Locale.GetText ("method string is null"));
+
+                       BindingFlags flags =  BindingFlags.Public | BindingFlags.Static;
+                       MethodInfo info = target.GetMethod (method, flags);
+                       return CreateDelegate_internal (type, null, info);
+               }
+
+               public static Delegate CreateDelegate (Type type, object target, string method, bool ignorecase)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException (Locale.GetText ("Type is null"));
+
+                       if (target == null)
+                               throw new ArgumentNullException (Locale.GetText ("Target object is null"));
+
+                       if (method == null)
+                               throw new ArgumentNullException (Locale.GetText ("method string is null"));
+                       
+                       Type target_type = target.GetType ();
+                       BindingFlags flags =  BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase;
+                       MethodInfo info = target_type.GetMethod (method, flags);
+                       return CreateDelegate_internal (type, target, info);                    
+               }
+
                public object DynamicInvoke( object[] args )
                {
                        return DynamicInvokeImpl( args );
@@ -76,6 +141,13 @@ namespace System {
 
                public virtual object DynamicInvokeImpl( object[] args )
                {
+                       if (Method == null) {
+                               Type[] mtypes = new Type [args.Length];
+                               for (int i = 0; i < args.Length; ++i) {
+                               mtypes [i] = args [i].GetType ();
+                       }
+                               method_info = m_target.GetType ().GetMethod (method_name, mtypes);
+                       }
                        return Method.Invoke( m_target, args );
                }
 
@@ -89,9 +161,6 @@ namespace System {
                        if ( o == null )
                                return false;
                        
-                       if ( o.GetType() != this.GetType() )
-                               return false;
-
                        Delegate d = (Delegate) o;
                        if ((d.target_type == target_type) &&
                            (d.m_target == m_target) &&
@@ -147,9 +216,8 @@ namespace System {
                {
                        Delegate retval = null;
 
-                       foreach ( Delegate next in delegates ) {
+                       foreach ( Delegate next in delegates )
                                retval = Combine( retval, next );
-                       }
 
                        return retval;
                }
@@ -160,21 +228,21 @@ namespace System {
                        throw new MulticastNotSupportedException ("");
                }
                
-               [MonoTODO]
-               public static Delegate Remove( Delegate source, Delegate value) {
+               
+               public static Delegate Remove( Delegate source, Delegate value ) 
+               {
                        if ( source == null )
                                return null;
                                
-                       if ( value == null )
-                               return source;
-
-                       throw new NotImplementedException ();
+                       return source.RemoveImpl( value );
                }
 
-               [MonoTODO]
-               protected virtual Delegate RemoveImpl(Delegate d)
+               protected virtual Delegate RemoveImpl( Delegate d )
                {
-                       throw new NotImplementedException();
+                       if ( this.Equals( d ) )
+                               return null;
+                      
+                       return this;
                }
 
                public static bool operator ==( Delegate a, Delegate b )