C#委托使用

版权声明:本文为Banana原创文章,未经Banana允许不得转载。评论请留下你认真观看后的想法或者意见,非常感谢! https://blog.csdn.net/qq1515312832/article/details/81538682

委托是啥

委托是一个类,它定义了方法的类型,说白了就是将一个方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法。

可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

 

Event关键字

它封装了委托类型的变量,使得:在类的内部,不管你声明它是public还是protected,它总是private的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同。

 

Tip

给委托增加或者减少方法使用-=和+=,使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。

 

一个例子

    class Program
    {
        static void Main(string[] args)
        {
            //此委托方法是在GreetingManager中定义的
            GreetingManager gm = new GreetingManager();
            gm.MakeGreet += EnglishGreeting;
            gm.GreetPeople("Man");
            gm.GreetPeople("先生");
            Console.ReadKey();
        }
        public static void EnglishGreeting(string name)
        {
            Console.WriteLine("Morning, " + name);
        }
        public static void ChineseGreeting(string name)
        {
            Console.WriteLine("你好," + name);
        }
    }

  

  //定义委托,定义了可以代表的方法的类型
    public delegate void GreetingDelegate(string name);
    public class GreetingManager
    {
        //在GreetingManager类中声明delegate1变量
        public event GreetingDelegate MakeGreet;
        public void GreetPeople(string name)
        {
            if(MakeGreet != null)//如果有方法注册委托变量
            {
                MakeGreet(name);//通过委托调用方法
            }
        }
    }

 

-=与+=的原理

MakeGreet事件确实是一个GreetingDelegate类型的委托,只不过不管是不是声明为public,它总是被声明为private。另外,它还有两个方法,分别是add_MakeGreet和remove_MakeGreet,这两个方法分别用于注册委托类型的方法和取消注册。实际上也就是: “+= ”对应 add_MakeGreet,“-=”对应remove_MakeGreet。而这两个方法的访问限制取决于声明事件时的访问限制符。

 

在add_MakeGreet()方法内部,实际上调用了System.Delegate的Combine()静态方法,这个方法用于将当前的变量添加到委托链表中。我们前面提到过两次,说委托实际上是一个类,在我们定义委托的时候:

public delegate void GreetingDelegate(string name);

当编译器遇到这段代码的时候,会生成下面这样一个完整的类:

public sealed class GreetingDelegate:System.MulticastDelegate{ 
    public GreetingDelegate(object @object, IntPtr method); 
    public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object); 
    public virtual void EndInvoke(IAsyncResult result); 
    public virtual void Invoke(string name); 
}

更多访问http://www.tracefact.net/tech/009.html

猜你喜欢

转载自blog.csdn.net/qq1515312832/article/details/81538682