本质上讲,代理提供了方法的封装,它把方法以某种方式封装在一个代理对象里,通过代理对象来执行调用方法、移除或者添加代理对象等操作。从另一种意义上讲,你可以把代理类型看作单一方法的接口,代理对象看作实现了该接口的对象。

  代理对象基础:代理类型

  下面的代码定义了一个代理类型


internal delegate void Feedback(Int32 value);


  C#编译器实际上将这个代理类型转化成为一个继承自MulticastDelegate的类。


internal class Feedback : System.MulticastDelegate
{
// Constructor
public Feedback(Object object, IntPtr method);
// Method with same prototype as specified by the source code
public virtual void Invoke(Int32 value);
// Methods allowing the callback to be called asynchronously
public virtual IAsyncResult BeginInvoke(Int32 value,
AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}


  MulticastDelegate继承自Delegate类,下面是代理类的签名:


public abstract class Delegate : ICloneable, ISerializable
    {
        protected Delegate(object target, string method);
        protected Delegate(Type target, string method);

        public static bool operator !=(Delegate d1, Delegate d2);
        public static bool operator ==(Delegate d1, Delegate d2);

        public MethodInfo Method { get; }
        public object Target { get; }

        public virtual object Clone();
        public static Delegate Combine(params Delegate[] delegates);
        public static Delegate Combine(Delegate a, Delegate b);
        protected virtual Delegate CombineImpl(Delegate d);
        public static Delegate CreateDelegate(Type type, MethodInfo method);
        public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure);
        public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method);
        public static Delegate CreateDelegate(Type type, object target, string method);
        public static Delegate CreateDelegate(Type type, Type target, string method);
        public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure);
        public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase);
        public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase);
        public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure);
        public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure);
        public object DynamicInvoke(params object[] args);
        protected virtual object DynamicInvokeImpl(object[] args);
        public override bool Equals(object obj);
        public override int GetHashCode();
        public virtual Delegate[] GetInvocationList();
        protected virtual MethodInfo GetMethodImpl();
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context);
        public static Delegate Remove(Delegate source, Delegate value);
        public static Delegate RemoveAll(Delegate source, Delegate value);
        protected virtual Delegate RemoveImpl(Delegate d);
    }
 
  这样的转化实际上定义了代理对象所有可能的操作,下面将一一列出

  一、构造并初始化代理对象

  常见的方式是使用下面的方式来构造并初始化代理对象


Feedback fbInstance = new Feedback(new Program().FeedbackToFile);


  然而,随着C#版本的升级,越来越多和代理有关的特性随之引入,同时也改变了代理对象的构造并初始化方式,例如在C#3.0中可以用匿名方法或者lambda表达式来构造并初始化代理对象。

  二、调用代理对象封装的方法

  这实际上是调用代理定义时编译器所生成的Invoke或者BeginInvoke方法,一个用于同步调用,另一个用于异步调用。