//
// System.Delegate.cs
//
// 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
//
using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
namespace System {
[MonoTODO]
public abstract class Delegate : ICloneable, ISerializable {
protected Type target_type;
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)
{
if (target == null)
throw new ArgumentNullException (Locale.GetText ("Target object is null"));
if (method == null)
throw new ArgumentNullException (Locale.GetText ("method name is null"));
this.target_type = null;
this.method_ptr = IntPtr.Zero;
this.m_target = target;
this.method_name = method;
}
protected Delegate (Type target_type, string method)
{
if (m_target == null)
throw new ArgumentNullException (Locale.GetText ("Target type is null"));
if (method == null)
throw new ArgumentNullException (Locale.GetText ("method string is null"));
this.target_type = target_type;
this.method_ptr = IntPtr.Zero;
this.m_target = null;
this.method_name = method;
}
public MethodInfo Method {
get {
return method_info;
}
}
public object Target {
get {
return m_target;
}
}
//
// 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 );
}
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 );
}
public virtual object Clone()
{
return MemberwiseClone();
}
public override bool Equals (object o)
{
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) &&
(d.method_name == method_name) &&
(d.method_ptr == method_ptr))
return true;
return false;
}
public override int GetHashCode ()
{
return (int)method_ptr;
}
// This is from ISerializable
[MonoTODO]
public void GetObjectData (SerializationInfo info, StreamingContext context)
{
// TODO: IMPLEMENT ME
}
public virtual Delegate[] GetInvocationList()
{
return new Delegate[] { this };
}
///
/// Returns a new MulticastDelegate holding the
/// concatenated invocation lists of MulticastDelegates a and b
///
public static Delegate Combine (Delegate a, Delegate b)
{
if (a == null){
if (b == null)
return null;
return b;
} else
if (b == null)
return a;
if (a.GetType () != b.GetType ())
throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types"));
return a.CombineImpl (b);
}
///
/// Returns a new MulticastDelegate holding the
/// concatenated invocation lists of an Array of MulticastDelegates
///
public static Delegate Combine( Delegate[] delegates )
{
Delegate retval = null;
foreach ( Delegate next in delegates )
retval = Combine( retval, next );
return retval;
}
protected virtual Delegate CombineImpl (Delegate d)
{
throw new MulticastNotSupportedException ("");
}
public static Delegate Remove( Delegate source, Delegate value )
{
if ( source == null )
return null;
return source.RemoveImpl( value );
}
protected virtual Delegate RemoveImpl( Delegate d )
{
if ( this.Equals( d ) )
return null;
return this;
}
public static bool operator ==( Delegate a, Delegate b )
{
if ((object)a == null) {
if ((object)b == null)
return true;
return false;
}
return a.Equals( b );
}
public static bool operator !=( Delegate a, Delegate b )
{
return !(a == b);
}
}
}