【C#】委托总结

委托在C#中最经常使用的特性之一,委托可以理解为C中的函数指针,但C#中的委托功能更强,使用更方便,本节总结一下关于C#的委托的使用

1、委托的使用

  委托相当于对函数的引用,通过委托可以直接使用该函数

  1)定义委托   2)实例化委托  3)使用委托

    //定义委托
    public delegate int AddDelegate(int a, int b);

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            //实例化委托
            AddDelegate adddelegate = new AddDelegate(p.Add);
            
            //此时,可以直接使用委托访问Add函数
            Console.Write("6 + 8 = {0}", adddelegate(6, 8));
        }

        public int Add(int a, int b)
        {
            return a + b;
        }
    }

2、泛型委托

    //定义委托
    public delegate T AddDelegate<T>(T a, T b);

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            //实例化委托
            AddDelegate<int> intadddelegate = new AddDelegate<int>(p.IntAdd);
            AddDelegate<double> doubleadddelegate = new AddDelegate<double>(p.DoubleAdd);
            
            Console.Write("6 + 8 = {0}", intadddelegate(6, 8));
            Console.Write("6.5 + 8.7 = {0}", doubleadddelegate(6.5, 8.7));
        }

        public double DoubleAdd(double a, double b)
        {
            return a + b;
        }
        public int IntAdd(int a, int b)
        {
            return a + b;
        }
    }

3、Func泛型委托

  Func泛型委托可以不需要定义委托,直接就可以使用,其中Func泛型委托的最后一个参数为返回值类型

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            
            Func<int, int, int> intadd = p.IntAdd;
            Func<double, double, double> doubleadd = p.DoubleAdd;

            Console.Write("6 + 8 = {0}", intadd(6, 8));
            Console.Write("6.5 + 8.7 = {0}", doubleadd(6.5, 8.7));
        }

        public double DoubleAdd(double a, double b)
        {
            return a + b;
        }
        public int IntAdd(int a, int b)
        {
            return a + b;
        }
    }

4、Action泛型委托

  Func泛型委托适用于带返回值的委托函数,而无返回值的委托可以用Action泛型委托

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            
            Action<string> showmsg = p.ShowString;

            showmsg("Hello");
        }

        public void ShowString(string msg)
        {
            Console.Write("显示:{0}", msg);
        }
    }

5、Predicate泛型委托

  Predicate泛型委托定义了一组条件,表示指定对象是否符合条件,返回值为bool类型,一般用于查找匹配,看例子就懂了

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Predicate<int> numgreatethan10 = p.IsNumGreaterThan10;
            
            //定义一组对象
            List<int> nums = new List<int> { 2, 3, 5, 8, 12, 25 };
            
            int firstnum = nums.Find(numgreatethan10);      //委托作为匹配条件用于查找
            List<int> all = nums.FindAll(numgreatethan10);
        }

        bool IsNumGreaterThan10(int a)
        {
            //判断a是否大于10
            if (a > 10)
                return true;
            else
                return false;
        }
    }

 6、匿名方法

   对于一些代码量小的函数,可以通过匿名委托来定义,让代码更简洁

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Func<int, int, int> intadd = delegate(int a, int b) { return a + b; };

            Console.Write("6 + 7 = {0}", intadd(6, 7));
        }
    }

7、Lambda表达式

  比起匿名方法,Lambda表达式更加简洁,只有参数,甚至连参数都可以不写

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Func<int, int, int> intadd = (a, b) => { return a + b; };

            Console.Write("6 + 7 = {0}", intadd(6, 7));
            Console.ReadKey();
        }
    }

 8、Invoke与委托

  在多线程编程时,后台线程可以通过委托让主线程更新UI,达到交互的目的

    1)首先定义一个委托  ProgressUpdate

    2)创建一个进度条控件  progressBar1,显示进度

    3)创建一个后台线程,通过委托更新进度

    public partial class Form1 : Form
    {
        public delegate void ProgressUpdate(int i);
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //创建线程
            new Thread(() => 
            {
                for (int i = 0; i <= 100; i++)
                {
                    this.Invoke(new ProgressUpdate(UpdateProgress), i);
                    Thread.Sleep(100);
                }
            }).Start();

        }
        private void UpdateProgress(int i)
        {
            this.progressBar1.Value = i;
        }
    }
原文地址:https://www.cnblogs.com/bomo/p/2865381.html