c#委托与事件、匿名函数与回调

委托

  • 什么是委托
//买家想买房子
class Buyer
{ 
    public House BuyHouse(float money,float area)
    { 
        //不知道谁能卖给他
    }
} 
//买家想执行但却不知如何实现,中介知道怎么去实现,买家委托中介
class Intermediary
{
    public House BuyHouse(float money, float area)
    {
        //可以帮助买家找房子
    }
} 
  • 委托类型与委托对象:
    在这里插入图片描述
  • 委托就是用来储存方法的结构
  • 委托的别名:代理、句柄,委托是自定义类型,委托是引用类型
  • 定义委托类型:delegate 返回值类型 委托类型名(参数列表);
delegate House BuyHouseEventHandle(float money, float area);
  • 委托对象:[访问修饰符] 委托类型名称 委托对象的名称;
public BuyHouseEventHandle buyHouseEventHandle; 
  • 给委托对象赋值:委托对象 = 方法名;
xiaoming.buyHoueEventHandle = intermediary.BuyHouse;
//注意只写方法名,没有括号,因为不是执行方法
//委托对象保存的是方法的内存地址
  • 委托对象的绑定与解绑定
xiaoming.buyHoueEventHandle += lianjia.BuyHouse; 
xiaoming.buyHoueEventHandle -= lianjia.BuyHouse; 
  • 委托对象的执行:委托对象(参数列表);
House house = xiaoming.buyHoueEventHandle(1000000,80);
//委托对象为空是不能执行的,执行前先提前判断
  • 系统委托类型:无返回值系统委托(Action<>)与有返回值系统委托(Func<>),可以不用自己定义类型,直接用系统委托类型,示例在最下面,也可自行查阅官方文档:MSDN Action的用法

匿名函数与回调

  • 匿名函数就是没有函数名的函数,匿名函数仅限委托绑定
  • 普通匿名函数方式绑定:委托对象 += delegate ([参数列表]){ };
xiaoming.buyHoueEventHandle += delegate(float m,float a) 
{    
	Console.WriteLine("匿名中介在帮忙找房子");
    return null;
}; 
  • 拉姆达表达式方式绑定:委托对象 += (参数列表) =>{ } ;
xiaoming.buyHoueEventHandle += (float m, float a) =>
{
    Console.WriteLine("匿名拉姆达表达式");
    return null;
}; 
  • 回调函数:可以理解为形参中是方法
public void Marry(BuyHouseEventHandle buyHouse)
{
    if(buyHouse == null)
    {
        Console.WriteLine(“No!!!!);
    }
    else
    {
        buyHouse(1000000,200);
        Console.WriteLine(”有房子啦,我好幸福!");
    }
} 

事件

  • 事件可以理解为一种特殊的委托对象:[访问修饰符] event 委托类型 事件名称
public event BuyHouseEventHandle buyHouseEvent;
  • 在非事件所在的类中,只能对事件进行绑定(+=)和解绑定(-=)
  • 在事件所在的类中,可以对事件进行赋值(=)、调用、绑定(+=)和解绑定(-=)

示例

  • 委托示例代码
	delegate void HelpFindHouseEventHandle(float money, float area);
    delegate void TestEventHanle<T>(T para);
    delegate void EmptyEventhanle();
    class Lianjia
    { 
        public void Fighting<T>(T words)
        {
            Console.WriteLine("链家员工正在喊口号:" + words);
        }
        
        public void HelpFindHouse(float money,float area)
        {
            Console.WriteLine("链家在帮忙找房子");
        }
    }

    class WoAiWoJia
    {
        public void HelpFindHouse(float money, float area)
        {
            Console.WriteLine("我爱我家在帮忙找房子");
        }
    }

    class MainClass
    {
        public static void Main(string[] args)
        {
            //委托对象
            HelpFindHouseEventHandle hfe;

            Lianjia lianjia = new Lianjia();
            WoAiWoJia woAiWoJia = new WoAiWoJia();

            hfe = lianjia.HelpFindHouse;
            hfe += woAiWoJia.HelpFindHouse;

            hfe(1000000, 200);

            //创建一个委托对象
            TestEventHanle<string> testEventHanle;
            //给委托对象赋值,存储链家喊口号的方法
            testEventHanle = lianjia.Fighting;
            TestEventHanle<int> intTestEventHanle;
            intTestEventHanle = lianjia.Fighting;
            testEventHanle("我最棒!");
            intTestEventHanle(1211234567);
        }
    }
  • 系统委托示例代码
	class House
    { 
        
    }

    class Person
    {
        private string name;

        public Person(string name)
        {
            this.name = name;
        }

        public House BuyHouse(float money,float area,string address)
        {
            Console.WriteLine($"{name}正在买房子...");

            Console.WriteLine($"{name}买房子需求:\n面积:{area}平米,预算:{money},地址:{address}...");

            return null;
        }

        public void SayHello()
        {
            Console.WriteLine($"{name}:SayHello");
        }

        //获取姓名
        public string GetName()
        {
            Console.WriteLine($"{name}正在返回姓名");
            return name;
        }

        public void Say(string words)
        {
            Console.WriteLine($"{name}正在讲话:{words}");
        }
    }

    class MainClass
    {
        public static void Main(string[] args)
        {
            Person xiaoming = new Person("小明");
            Action action;
            action = xiaoming.SayHello;
            action();
            Action<string> stringAction;
            stringAction = xiaoming.Say;
            stringAction("你好厉害!");
            Func<string> func;
            func = xiaoming.GetName;
            //调用委托对象
            Console.WriteLine(func());
            Func<float, float, string, House> houseFunc;
            //给委托类型赋值
            houseFunc = xiaoming.BuyHouse;
            //调用委托
            House house = houseFunc(2000000, 400, "北京五环");
        }
    }
  • 匿名函数示例代码
	class Person
    {
        public Action<string> stringAction;
        private string name;
        public Person(string name)
        {
            this.name = name;
        }
        /// <summary>
        /// 朗读文章
        /// </summary>
        /// <param name="words">Words.</param>
        public void ReadWords(string words)
        {
            Console.WriteLine($"{name}朗读英文文章");

            if (stringAction != null)
            {
                stringAction(words);
            }
        }
    }
    class MainClass
    {
        public static void Main(string[] args)
        {
            Person xiaoming = new Person("xiaoming");

            xiaoming.stringAction = delegate (string str) {
                Console.WriteLine("在Main中朗读文章");
                Console.WriteLine("文章内容:" + str);
            };

            xiaoming.stringAction += (string words) => {
                //方法体
                Console.WriteLine("在拉姆达表达式中朗读文章");
                Console.WriteLine("文章内容:" + words);
            };

            xiaoming.stringAction += Read;
            xiaoming.ReadWords("Hello World...");
        }
        public static void Read(string words)
        {
            Console.WriteLine("在静态函数中朗读文章");
            Console.WriteLine("文章内容:" + words);
        }
    }
  • 回调函数示例代码:
class Person
    {
        private string name;
        /// <summary>
        /// 电话本【联系册】
        /// </summary>
        private Dictionary<string, Action<string>> relationBook;

        public Person(string name)
        {
            this.name = name;
            relationBook = new Dictionary<string, Action<string>>();
        }

        /// <summary>
        /// 设置联系方式
        /// </summary>
        public void SetRelationFunction(string name,Action<string> relationFunc)
        {
            Console.WriteLine($"{name}已经将联系方式给了:" + this.name);
            //将联系方式添加到电话本
            relationBook.Add(name, relationFunc);
        }

        public void CallSomeOne(string name)
        {

            if (relationBook.ContainsKey(name))
            {
                Console.WriteLine($"{this.name}正在打电话联系{name}...");
                //联系他
                relationBook[name](this.name);
            }
            else
            {
                Console.WriteLine($"电话本中没有找到{name}的电话号码...");
            }

        }

        public void CallMe(string name)
        {
            Console.WriteLine($"{name}正在联系{this.name} ...");
            Console.WriteLine("联系建立...Chating...");
        }
    }

    class MainClass
    {
        public static void Main(string[] args)
        {
            Person xiaoming = new Person("小明");
            Person xiaohong = new Person("小红");
            xiaohong.SetRelationFunction("小明", xiaoming.CallMe);
            Console.WriteLine("---------------");
            xiaohong.CallSomeOne("小明");
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章