委托

想把要调用的函数定义为一个变化的参数,把要它逐个处理的函数定义为一个参数,我传递哪个参数,它就调用哪个参数
View Code
 //1先声明一个委托
        delegate string DelMethod(string str);
        static void Main(string[] args)
        {
            string[] strs = { "AAVV", "ChWn", "FFccc", "aaJJ" };
            //2定义委托,让委托指向方法
            DelMethod del = new DelMethod(ToUpper);
            //3调用委托
            StringProcess(strs, del);
            Console.WriteLine(string.Join("-",strs));
        }

        static void StringProcess(string[] strs,DelMethod del)
        {
            for (int i = 0; i < strs.Length; i++)
            {
                strs[i] = del(strs[i]);
            }
        }
        static string ToLower(string str)
        {
            return str.ToLower();
        }
        static string ToUpper(string str)
        {
            return str.ToUpper();
        }

让委托指向方法,可以直接这么写DelMethod del = ToUpper;

熟练后就可以 直接使用StringProcess(strs, Toupper);

只要声明一个委托,让它的签名与方法一样,那么把委托作为参数时就可以调用那个方法了;

还可以直接写个匿名方法来使用委托:

DelMethod del = delegate(string str) { return str.ToUpper(); };

第一个例子,我们要比较int数组里最大的数、字符串里最长的数、Person类里年龄最大的数,使用委托来实现:

View Code
 class Person
    {
        public Person() { }
        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        public override string ToString()
        {
            return name;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            object[] objInt = {1,2,3,4,5,6,7 };
            object[] objString = { "a", "ab", "abc", "abcd" };
            object[] objPerson = { new Person("张三", 15), new Person("李四", 21), new Person("老五", 30) };
            Console.WriteLine(GetMax(objInt, IntCompare));
            Console.WriteLine(GetMax(objString, StringCompare));
            Console.WriteLine(GetMax(objPerson, PersonCompare));
            Console.ReadKey();
        }
        delegate int DelMethod(object o1,object o2);

        static int PersonCompare(object o1, object o2)
        {
            Person num1 = (Person)o1;
            Person num2 = (Person)o2;
            return num1.Age - num2.Age;
        }

        static int StringCompare(object o1, object o2)
        {
            string num1 = (string)o1;
            string num2 = (string)o2;
            return num1.Length - num2.Length;
        }

        static int IntCompare(object o1, object o2)
        {
            int num1 = (int)o1;
            int num2 = (int)o2;
            return num1 - num2;
        }
        static object GetMax(object[] arr,DelMethod del)
        {
            object Max=arr[0];
            for (int i = 0; i < arr.Length; i++)
            {
                if (del(Max,arr[i])<0)
                {
                    Max = arr[i];
                }
            }
            return Max;
        }
    }

第二个例子,跟上面的一样,只是我们是要排序,把他们按从小到大的顺序输出来:

这里是用冒泡算法来排序的
 class Person
    {
        public Person() { }
        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        public override string ToString()
        {
            return name;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            object[] objInt = {1,2,3,4,5,6,7 };
            object[] objString = { "a", "ab", "abc", "abcd" };
            object[] objPerson = { new Person("张三", 15), new Person("李四", 21), new Person("老五", 30) };

            Sort(objInt, IntCompare);
            Sort(objString, StringCompare);
            Sort(objPerson, PersonCompare);
            Console.WriteLine(string.Join("-", objInt));
            Console.WriteLine(string.Join("-", objString));
            Console.WriteLine(string.Join("-", objPerson));
            Console.ReadKey();
            
        }
        delegate int DelMethod(object o1,object o2);
        
        static int PersonCompare(object o1, object o2)
        {
            Person num1 = (Person)o1;
            Person num2 = (Person)o2;
            return num1.Age - num2.Age;
        }

        static int StringCompare(object o1, object o2)
        {
            string num1 = (string)o1;
            string num2 = (string)o2;
            return num1.Length - num2.Length;
        }

        static int IntCompare(object o1, object o2)
        {
            int num1 = (int)o1;
            int num2 = (int)o2;
            return num1 - num2;
        }

        static void Sort(object[] arr, DelMethod del)
        {
            bool isChanged = false;
            for (int i = 0; i < arr.Length; i++)
            {
                isChanged = false;
                for (int j = 0; j < arr.Length-1-i; j++)
                {
                    if (del(arr[j], arr[j + 1])>0)
                    {
                        object item = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = item;
                        isChanged = true;
                    }
                }
                if (!isChanged)
                    break;
            }
        }
    }

第三个例子,我们使用系统带的排序方法; 

系统里带的Sort排序方法,数字是从小到大排序的,字符串是按从a到z排序的;

Sort()方法参数有个委托参数,public delegate int Comparison<in T>(T x, T y);所以我们可以按照它的签名来写一个方法,实现我们想要的排序

Sort方法
 class Person
    {
        public Person() { }
        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        public override string ToString()
        {
            return name;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<int> listInt = new List<int>{1,2,3,4,5,6,7 };
            List<string> listString = new List<string>() { "d", "ba", "cba", "dcba" };
            List<Person> listPerson = new List<Person>() { new Person("张三", 15), new Person("李四", 21), new Person("老五", 30) };
     
            listInt.Sort();
            listString.Sort(StringCompare);
            listPerson.Sort(PersonCompare);
            Console.WriteLine(string.Join("-", listInt));
            Console.WriteLine(string.Join("-", listString));
            Console.WriteLine(string.Join("-", listPerson));
            
            Console.ReadKey();
                
        }
        static int StringCompare(string s1, string s2)
        {
            return s1.Length - s2.Length;
        }
        static int PersonCompare(Person p1, Person p2)
        {
            return p1.Age - p2.Age;
        }
    }

可以使用委托实现用户登录控件,让不同的窗体使用时可以实现不同的操作(调用不同的数据库来操作);

委托是一个数据类型,要实例化后才能调用
       //1声明委托
        public  delegate void DelMethod(string userName, string pwd);
        //2让委托指向方法
        public DelMethod del;
        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                MessageBox.Show("用户名不能为空");
            }
            else if (string.IsNullOrEmpty(textBox2.Text))
            {
                MessageBox.Show("密码不能为空");
            }
            else
            {
                 //DelMethod(textBox1.Text, textBox2.Text)这么写不对
                if (del != null)//委托指向的方法不为null时;
                {
                    //3.调用委托
                    del(textBox1.Text, textBox2.Text);
                }
            }
        }    
给委托添加方法
        private void Form1_Load(object sender, EventArgs e)
        {
            ucLogin1.del = new UCLogin.DelMethod(Login);
        }
        static void Login(string user, string pwd)
        {
            if (user == "admin" && pwd == "admin")
            {
                MessageBox.Show("登陆成功");
            }
            else
            {
                MessageBox.Show("用户名密码不正确");
            }
        }

 为什么说事件就是委托,可以使用反编译看一下,事件其实就是封装了委托,还有两个方法;跟属性差不多。

使用事件来实现上面的用户登录的例子:

用事件实现
        public  delegate void DelMethod(string name, string pwd);
        public event DelMethod del;//定义一个事件
        private void button1_Click_1(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                MessageBox.Show("用户名不能为空");
                return;
            }
            else if (string.IsNullOrEmpty(textBox2.Text))
            {
                MessageBox.Show("密码不能为空");
                return;
            }
            else
            {
                if (del != null)
                {
                    del(textBox1.Text, textBox2.Text);
                }
            }
        }
View Code
        private void Form1_Load(object sender, EventArgs e)
        {
            //+=后面直接两个Tab键就可以添加事件了
            ucLogin1.del += new UCLogin.DelMethod(ucLogin1_del);
        }

        void ucLogin1_del(string name, string pwd)
        {
            if (name == "admin" && pwd == "admin")
            {
                MessageBox.Show("登陆成功");
            }
            else
            {
                MessageBox.Show("用户名密码不正确");
            }
        }
原文地址:https://www.cnblogs.com/hejinyang/p/2810710.html