Пример #1
0
 public static void Transform(int[] values, Transformr t)
 {
     for (int i = 0; i < values.Length; i++)
     {
         values[i] = t(values[i]);
     }
 }
Пример #2
0
        static void Main(string[] args)
        {
            //委托类型定义了委托实例可以调用的那类方法,具体来说委托类型定义了方法的返回类型和参数
            Transformr t = Square; //把方法赋值给委托变量的时候就创建了委托实例 正规写法:Transformr t=new Transformr(Square)
            //在这里通过委托调用Square方法,使得调用者(Main)和被调用者(Square)解耦了
            int answer = t(3);     //answer=9;委托实例调用目标方法 正规写法int answer=t.Invoke(3);

            int[] values = { 1, 2, 3 };
            Util.Transform(values, Square);
            foreach (int i in values)
            {
                Console.WriteLine($"{i} ");
            }
            //泛型委托
            UtilGeneRic.Transform <int>(values, Square);
            foreach (var i in values)
            {
                Console.WriteLine($"{i} ");
            }
            //Func就是一种封装好的泛型委托,最后一个参数是输出,返回类型和最后一个参数一致,其他参数是输入,若只有一个参数,那这个参数是输出
            //Action无返回类型,所有参数都是输入


            //多播委托

            /*
             * 使用+和+=操作符可以合并委托实例
             * SomeDeleGate d=SomeMethod1;
             * d+=SomeMethod2;
             * 这样子调用d就会调用SomeMethod1和SomeMethod2;而委托的调用顺序和它们的定义顺序一致
             * 同理-和-=类似
             * 委托的使用+-时操作数可以是null,
             * SomeDelegate d=null;
             * d+=SomeMethod1;
             * 上面两句相当于d=SomeMethod1;
             *
             * 注意:委托实质是不可变的,使用+=或者-=时,时机上是创建了新的委托实例,并把它赋给当前的委托变量
             * 如果多播委托的返回类型不是void,那么调用者会从最后一个被调用的方法来接收返回值,前面的方法仍然会被调用,但是其返回值就被丢弃了
             */

            //委托能解决的问题,接口都可以解决
            //但是在以下条件之一满足时,更适合使用委托
            //1.接口只能定义一个方法
            //2.需要多播能力
            //3.订阅者需要多次实现接口

            //委托类型之间无论怎么都互不相容,只要名字不一样就不一样
            //若委托实例拥有相同的目标方法,则委托实例被认为是相等的

            //委托的兼容性-参数
            //当调用一个方法时,委托的参数可以比方法的参数更加具体(即委托参数是方法的子类依旧可以调用)
            //例子如下
            //delegate void StringAction(string s);
            //static void ObjectAction(object o) => Console.WriteLine(o);
            //StringAction sa = new StringAction(ObjectAction);
            //sa("Hello");

            //委托的兼容性-返回类型
            //调用方法时,可以得到一个比请求的类型更具体的类型的返回结果
            //例子如下
            //delegate object ObjectRetriever();
            //static string RetrieveString() => "Hello";
            //ObjectRetriever o= new ObjectRetriever(RetrieveString);
            //object result= o()
        }