C#学习记录-委托

 普通委托

在类里注册委托,而不是方法里;

定义委托可以用元组的方法;

委托添加方法时不能加括号,加括号相当于调用了此方法,使用委托时再加括号;

委托可以传入另外一个方法。

namespace _06_委托
{
    internal class Program
    {
        delegate void IntMethodInvoker(int i);
        delegate long TwoLong(long a, long b);
        delegate string GetAString();
        delegate int GetIntegerDelegate(int a);

        static void Main(string[] args)
        {
            IntMethodInvoker invoker = null;
            TwoLong invoker2 = null;
            invoker += test;
            invoker(100);
            if(invoker2 != null)
            {
                invoker2(100, 20);
            }
            int x = 123;
            GetAString invoker3 = null;
            invoker3 += x.ToString; 
            Console.WriteLine(invoker3());

            GetIntegerDelegate[] invoker4 = { Class1.Squarenum,Class1.Doublenum};
            foreach(GetIntegerDelegate getIntegerDelegate in invoker4)
            {
                SquarOrDouble(getIntegerDelegate, 3);
                //Console.WriteLine("数字3的平方或两倍为:" + getIntegerDelegate(3));
            }
            
        }

        static private void SquarOrDouble(GetIntegerDelegate op ,int val)
        {
            Console.WriteLine($"数字{val}的平方或两倍为:" + op(val));
        }


        private static void test(int i)
        {
            Console.WriteLine("委托调用了我的数字:"+i);
        }

        public static int Doublenum(int a)
        {
            return a * 2;
        }
        public static int Squarenum(int a)
        {
            return a * a;
        }
    }
}

Action委托

这类委托时系统提前注册过的,方便调用;

无返回值;

有参时,需要在定义时用泛型;

namespace _07_Action委托
{
    internal class Program
    {
        static void Test1()
        {
            Console.WriteLine("无参数方法一");
        }

        static void Test2(int a)
        {
            Console.WriteLine("参数一:"+a.ToString());
        }

        static void Test3(int a , double b)
        {
            Console.WriteLine("参数一:" + a.ToString()+"。参数二:"+b.ToString());
        }

        static void Main(string[] args)
        {
            Action method1 = Test1;
            method1();

            Action method2 = Test2;
            method2(5);

            Action method3 = Test3;
            method3(5,3.14159026);
        }
    }
}

Func委托

这类委托时系统提前注册过的,方便调用;

有返回值,需要在定义时用泛型确定返回类型;

有参时,需要在定义时用泛型,最后一个为返回值;

namespace _08_Func委托
{
    internal class Program
    {
        static string Test1()
        {
            return "ljc";
        }

        static string Test2(int a, double b, string c)
        {
            return a.ToString() + b.ToString() + c;
        }


        static void Main(string[] args)
        {
            Func method1 = Test1;
            Console.WriteLine(method1()); 

            Func method2 = Test2;
            Console.WriteLine(method2(6, 6.6, "六六"));
        }
    }
}

升级版冒泡排序

结合了泛型、委托,让排序可以对任意类型排序;

需要传入元素比较方法

namespace _09_冒泡排序升级版
{
    internal class Employee
    {
        public string name { get; private set; }
        public int age { get; private set; }

        public Employee(string name, int age)
        {
            this.name = name;
            this.age = age;
        }

   
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Employee[] Employees =
            {
                new Employee("ask",23),
                new Employee("fxcz", 29),
                new Employee("hgf", 26),
                new Employee("nbv", 18),
                new Employee("nbm", 44),
                new Employee("ytr", 33),
            };
            Func< Employee, Employee, bool> d = compare;
            sort(Employees, d);
            foreach (Employee emp in Employees)
            {
                Console.WriteLine(emp.name+" age: "+emp.age);
            }
        }


        static void sort(T[] arr, Func a)
        {
            bool flag;
            T arrflag;
            
            do
            {
                flag = false;
                for (int i = 0; i< arr.Length-1; i++)
                {
                    if (a(arr[i] , arr[i+1]))
                    {
                        arrflag = arr[i];
                        arr[i] = arr[i + 1];
                        arr[i + 1] = arrflag;
                        flag = true;
                    }
                }
            } while (flag);
        }

        static bool compare(Employee a, Employee b)
        {
            return a.age > b.age;
        }
    }
}

多播委托

  1. GetInvocationList方法: GetInvocationList方法是Delegate类提供的一个方法,用于获取委托所绑定的所有方法的数组。
  2. DynamicInvoke方法: DynamicInvoke方法是Delegate类提供的一个方法,用于动态调用委托所表示的方法。通过DynamicInvoke方法,可以在运行时根据委托的签名来调用相应的方法。
namespace _10_多播委托
{

    internal class Program
    {
        static void Test1()
        {
            Console.WriteLine("测试1");
        }
        static void Test2()
        {
            Console.WriteLine("测试2");
        }

        static void Main(string[] args)
        {
            Action action = Test1;
            action += Test2;
            action += Test2;
            action -= Test2;
            Delegate[] delegates = action.GetInvocationList();
            foreach (Delegate d in delegates)
            {
                d.DynamicInvoke();
            }
        }
    }
}

匿名方法、lamda表达式

注意lamda表达式可以调用表达式之外的参数,但是尽量别这样做。

namespace _11_匿名方法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Func func = (x, y) => x + y;
            Func func1 = delegate (int x, int y)
            {
                return x + y;
            };
            Console.WriteLine(func(1,2));
            Console.WriteLine(func1(1, 2));


            int a = 6;
            Func func2 = (x, y) => x + y + a;
            Console.WriteLine(func2(1, 2));
            a = 10;
            Console.WriteLine(func2(1, 2));
        }
    }
}

工具人下楼-事件

事件是受限制的委托,目的是为了防止误操作:

1.只能在类内调用使用;

2.类外只能 +=  -= 操作,不能=。

namespace _12_工具人下楼
{
    delegate void DownStairDeleget();
    internal class ToolMan
    {
        public event DownStairDeleget downStairDeleget = null;
        public string name { get;private set; }
        public ToolMan(string name)
        {
            
            this.name = name;
        }
        public void DownStair()
        {
            Console.WriteLine(name + "下楼了");
            if(downStairDeleget != null)
            {
                downStairDeleget();
            }
        }
    }
    internal class LazyMan
    {
        public string name { get; private set; }
        public LazyMan(string name)
        {
            this.name = name;
        }

        public void TakeFood()
        {
            Console.WriteLine(name+"需要拿外卖");
        }
        public void TakePackge()
        {
            Console.WriteLine(name + "需要拿快递");
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            ToolMan toolman = new ToolMan("小罗");
            LazyMan lazyMan1 = new LazyMan("小刘");
            LazyMan lazyMan2 = new LazyMan("小王");
            LazyMan lazyMan3 = new LazyMan("小李");
            LazyMan lazyMan4 = new LazyMan("小周");

            
            //toolman.downStairDeleget = lazyMan1.TakePackge;
            toolman.downStairDeleget += lazyMan2.TakeFood;
            toolman.downStairDeleget += lazyMan3.TakePackge;
            toolman.downStairDeleget += lazyMan4.TakeFood;
            //toolman.downStairDeleget();
            toolman.DownStair();
        }
    }
}

你可能感兴趣的:(c#,学习,开发语言)