2016年8月29日 星期一

用簡易的範例快速瞭解 c# delegate 的前世今生

深入研究asp.net core 需要了解 delegate, 所以做筆記複習一下:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp2
{
    // 定義一個委派型別
    public delegate bool Predicate(string s); 

    // 定義一個類別
    public class FruitList 
    {
        private List<string> fruits;

        public FruitList()
        {
            fruits = new List<string> { "Apple", "Banana", "Mango" };
        }
        public string Find(Predicate p)
        {
            for (int i = 0; i < fruits.Count(); i++)
            {
                var f = fruits[i];
                var isMatch = p(f); // 執行委派任務, 等同於  p.Invoke(f)
                if (isMatch)
                {
                    return f;
                }
            }
            return "";
        }
    }
    // demo c# 1.0
    public class Demo1
    {
        public void Run()
        {
            FruitList fruits = new FruitList();
            Predicate p = new Predicate(FindApple); // 建立委派物件. 可以加入多項工作, 例如 : p += new Predicate(FindBanana);
            string f = fruits.Find(p);
            Console.WriteLine(f);
        }

        private bool FindApple(string s)
        {
            return s == "Apple";
        }
    }
    // c# 2.0 : 匿名方法
    public class Demo2
    {
        public void Run()
        {
            FruitList fruits = new FruitList();
            Predicate p1 = FindBanana;  // 編譯器看到變數是委派型別, 便會自動加上 new 
            string f1 = fruits.Find(p1); 
            string f2 = fruits.Find(FindBanana); // 簡化 f1
            Console.WriteLine(f1);

            // 使用匿名方法
            Predicate p3 = delegate (string s) { return s == "Banana"; };
            string f3 = fruits.Find(p3);
            //
            Console.WriteLine(f3);
        }

        private bool FindBanana(string s)
        {
            return s == "Banana";
        }
    }
    // c# 3.0 : Lambda
    public class Demo3
    {
        public void Run()
        {
            FruitList fruits = new FruitList();
            Predicate p1 = (string s) => { return s == "Mango"; }; // Lambda 取代了匿名方法
            Predicate p2 = (string s) => s == "Mango"; // 簡化 p1 寫法
            Predicate p3 = s => s == "Mango"; // 簡化 p2 寫法
            string f1 = fruits.Find(p3);
            string f2 = fruits.Find(s => s == "Mango"); // 簡化 f1 
            Console.WriteLine(f2);
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var d = new Demo3();
            d.Run();
            Console.ReadKey();
        }
    }
}

沒有留言: