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("小明");
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章