委托学习(一)

之前有学过,但也是一知半解,现在有空重新去查找一些资料学习了一下,虽然也是从别人那儿学来的,但是也正努力的根据自己的理解去写例子。

  • 通过实例了解委托的概念
  • 委托的回调
  • 委托的深入(委托链 - 合并删除委托)
  • 委托的源码解析
  • 泛型委托
  • 委托的进步(语法糖,协变和逆变,匿名,闭包)
  • 委托链、泛型委托源码解析
  • 委托和反射
  • 异步委托

1.通过实例了解委托的概念

 什么是委托?:委托是一种类型,属于引用类型,委托的关键字:delegate。委托与类的定义是一样的,能定义类的地方也能定义委托。

 如何创建一个无参和有参的委托?

   案例1:委托的基本组成

class Program
    {
        delegate void myDelegate_No();
        delegate void myDelegate_Have(string Name);
        static void Main(string[] args)
        {
            myDelegate_No myDelegate_No = new myDelegate_No(MyMethod);
            myDelegate_No();
            myDelegate_Have myDelegate_Have = new myDelegate_Have(MyMethod);
            myDelegate_Have("Have");
            Console.Read();
        }
        public static void MyMethod()
        {
            Console.WriteLine("创建一个无参的方法");
        }
        public static void MyMethod(string Name)
        {
            Console.WriteLine("创建了一个有参的方法,传入一个名字为:"+Name);
        }
    }
View Code

2.委托回调静态方法和实例方法

 回调函数怎么理解?或者说回调函数为什么被成为回调函数?

 比如调用了一个函数,那么就叫做调用,但是如果在调用一个函数A的时候还需要把这个函数A提交给该函数B,让函数B调用函数A,那么提供的函数A就成为回调函数  (callBack)

  理解上述描述之后再来理解“委托回调”也就不难理解了。

  案例2:委托回调

class Program
    {
        delegate void MyDelegate();
        static void Main(string[] args)
        {
            //委托回调静态方法
            MyDelegate myDelegate = new MyDelegate(StudyDelegateInstance.getFirstDelegateCallBack);
            myDelegate.Invoke();
            //委托回调实例方法
            StudyDelegate studyDelegate = new StudyDelegate();
            MyDelegate myDelegate_Instance = new MyDelegate(studyDelegate.getFirstDelegateCallBack);
            myDelegate_Instance.Invoke();
        }
    }

    public  class StudyDelegate
    {
        public  void getFirstDelegateCallBack()
        {
            Console.WriteLine("这是写的第一个回调委托的实例方法");
        }
        
    }
    public class StudyDelegateInstance
    {
        public static void getFirstDelegateCallBack()
        {
            Console.WriteLine("这是写的第一个回调委托的静态方法");
        }
    }
View Code

3.委托的合并与删除 

  学习这个是为了学习【委托链】,这个会在后文进行补充和学习 

  案例3:委托的合并和删除

class Program
    {
        delegate void MyDelegate();
        static void Main(string[] args)
        {
            MyDelegate myDelegate = new MyDelegate(StudyDelegateInstance.getFirstDelegateCallBack);
            StudyDelegate studyDelegate = new StudyDelegate();
            MyDelegate myDelegate_Instance = new MyDelegate(studyDelegate.getFirstDelegateCallBack);
            //委托的合并
            var delegate_Combine= (MyDelegate)Delegate.Combine(myDelegate,myDelegate_Instance);
            //相当于:var delegate_Combine = myDelegate += myDelegate_Instance;
            delegate_Combine.Invoke();
            //委托的与删除
            var delegate_Rmove = (MyDelegate)Delegate.Remove(delegate_Combine,myDelegate);
            //相当于 var delegate_Rmove = delegate_Combine - myDelegate;
            delegate_Rmove.Invoke();
            Console.ReadLine();
        }
    }

    public  class StudyDelegate
    {
        public  void getFirstDelegateCallBack()
        {
            Console.WriteLine("这是写的第一个回调委托的实例方法");
        }
        
    }
    public class StudyDelegateInstance
    {
        public static void getFirstDelegateCallBack()
        {
            Console.WriteLine("这是写的第一个回调委托的静态方法");
        }
    }
View Code
Remove(source,value)新的委托,其调用列表的构成采用的调用列表 source 和删除的调用列表的最后一个匹配项 value, ,如果的调用列表 value 的调用列表中找到 source。 返回 source 如果 value 是 null 或者,如果的调用列表 value 的调用列表中找不到 source。 如果返回 null 引用的调用列表 value 的调用列表等于 source 或者,如果 source 为空引用。

4.泛型委托

  c#变成指南给出的解释和案例(属于自定义的泛型委托)。泛型的好处是减少复杂性,提高可重用性,参考文章来源:http://www.cnblogs.com/DeepLearing/p/4554867.html#3211258

引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型,就像实例化泛型类或调用泛型方法一样
public delegate void Del<T>(T item);
public static void Notify(int i) { }
Del<int> m1 = new Del<int>(Notify);

 其实在c#2.0版之后提供了两种泛型委托:Action和Func.

   Action:.NET FreamWork提供了17个Action委托,从无参数到16个参数,如果超过16个就需要自己定义了,同时Action并不带有返回值。

   案例4:

class Program
    {
        
        static void Main(string[] args)
        {
            Action<string, int, string> ActionStudent = new Action<string, int, string>(Student);
            ActionStudent.Invoke("c#",2,"c#学习书本");
            Console.ReadKey();
        }
        public static void Student(string Name,int Age,string Address) {
            Console.WriteLine("名字:"+Name+",年龄:"+Age+",地址:"+Address);
        }
    }
View Code

   Func:一样提供了从无参到16个参数外加一个返回值。

   案例5:

static void Main(string[] args)
        {
            Func<string,int, string,string> FuncStudent = new Func<string, int, string,string>(Student);
            string studentFunc = FuncStudent.Invoke("c#",2,"c#学习书本");
            Console.WriteLine(studentFunc);
            Console.ReadKey();
        }
        public static string Student(string Name,int Age,string Address) {
            string studentInfo = "名字:" + Name + ",年龄:" + Age + ",地址:" + Address;
            return studentInfo;
        }
View Code

参考网址: http://www.cnblogs.com/DeepLearing/p/4594518.html 

原文地址:https://www.cnblogs.com/zmztya/p/6265638.html