zoukankan      html  css  js  c++  java
  • 【C#】学习笔记(1) Delegates,Events,Lambda Expressions

    C#是跟着杨老师的教程走的,在这里感谢一下老师的无私奉献,他的cnblog地址:>cgzl,他的B站地址:>solenovex

    进入正题:

      Delegate表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。(引用官方文档的英文原话)

      Represents a delegate, which is a data structure that refers to a static method or to a class instance and an instance method of that class.

      看不懂没关系,我也看不懂,哈哈哈。

      直接拿两个例子看一下,第一个是杨老师提供的。

      

     1 using System;
     2 
     3 namespace Demo
     4 {
     5     class Program
     6     {
     7         // 定义一个名为Transformer的delegate类,参数类型int,返回类型int。
     8         delegate int Transformer(int x);
     9         // 定义一个静态类Square,这里用了Lambda表达式,同样的,参数类型为int,返回类型也是int。
    10         static int Square(int x) => x * x; 
    11         static void Main(string[] args)
    12         {
    13             Transformer t = Square; //把Square方法当作变量传入委托变量t,这时创建了委托实例。
    14             int result = t(3);  // 调用委托方法。
    15             Console.WriteLine(result); // 输出结果:9
    16         }
    17     }
    18 }

     这里的 Transformer t= Square; 简写了,等效于Transformer t= new Transformer(Square);

    也就是当调用t(3)(委托实例)时,先调用了委托,委托再去调用目标方法。画个图应该很好理解。

    优点:解耦。

    应用:编写插件式的方法

      ·方法是在运行时才赋值给委托变量的

      

     1 using System;
     2 
     3 namespace Demo
     4 {
     5     public delegate int Transformer(int x); // 定义委托类要注意传入的类型和返回类型。
     6 
     7     class Util
     8     {
     9         public static void Transform(int[] values, Transformer t) 
    10         {
    11             for (int i = 0; i < values.Length; i++)
    12             {
    13                 values[i] = t(values[i]); // 委托实例t
    14             }
    15         }
    16     }
    17     class Program
    18     {
    19         static int Square(int x) => x * x;
    20         public static void Main(string[] args)
    21         {
    22             int[] values = { 1, 2, 3 };
    23             Util.Transform(values, Square); // 这里调用Util的静态方法Transform,并传入参数。目标函数为Square
    24             foreach (int i in values)
    25             {
    26                 Console.WriteLine(i);
    27             }
    28         }
    29     }
    30 }

     接下来看一下官方文档给的例子:>Delegate

     1 using System;
     2 
     3 namespace Demo
     4 {
     5     public delegate String myMethodDelegate(int myInt);
     6 
     7     public class mySampleClass
     8     {
     9         public String myStringMethod(int myInt)
    10         {
    11             if (myInt>0)
    12             {
    13                 return ("positive");
    14             }
    15             if (myInt<0)
    16             {
    17                 return ("negative");
    18             }
    19             return ("zero");
    20         }
    21         public static String mySignMethod(int myInt)
    22         {
    23             if (myInt > 0)
    24             {
    25                 return ("+");
    26             }
    27             if (myInt < 0)
    28             {
    29                 return ("-");
    30             }
    31             return ("");
    32         }
    33     }
    34 
    35     class Program
    36     {
    37         public static void Main(string[] args)
    38         {
    39             // Creates one delegate for each method. For the instance method, an
    40             // instance (mySC) must be supplied. For the static method, use the
    41             // class name.
    42             mySampleClass mySC = new mySampleClass();
    43             myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);
    44             myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod);
    45 
    46             // Invokes the delegates.
    47             Console.WriteLine("{0} is {1}; use the sign "{2}".", 5, myD1(5), myD2(5));
    48             Console.WriteLine("{0} is {1}; use the sign "{2}".", -3, myD1(-3), myD2(-3));
    49             Console.WriteLine("{0} is {1}; use the sign "{2}".", 0, myD1(0), myD2(0));
    50         }
    51     }
    52 }

    运行结果:

    画个图分析一下:

    多播委托

      委托按着我自己的理解就是把别人的方法放到我这儿,要用的时候去拿,但是不是在我这儿拿,而是到别人那去。em

       多播委托就是可以利用操作符+,-来创建新的委托实例,并赋值给当前的委托变量。

       

    using System;
    
    namespace Demo
    {
        public delegate int Transformer(int x);
        class Program
        {
            static int Square(int x)
            {
                var result = x * x;
                Console.WriteLine(result);
                return result;
            }
            static int Cube(int x)
            {
                var result = x * x * x;
                Console.WriteLine(result);
                return result;
            }
            public static void Main(string[] args)
            {
                Transformer t = null;
                t += Square;
                t += Cube;
                t(3);
            }
        }
    }

    输出结果:

    Square在先,它就先执行。

    假如都进行-=移除,最后会报空指针异常。

      委托实例里至少要有一个静态对象或者是实例对象,不然会抛出空指针异常。

    A combining operation returns null when the result of the operation is a delegate that does not reference at least one method.

    “委托是不可变的“

    Combine 和Remove实际上是创建新的委托实例,并把它赋给当前的委托变量”。

    感觉自己理解有不对的地方,就先这样吧。

  • 相关阅读:
    如何为创建大量实例节省内存?
    4-5
    4-6
    4-4
    4-3
    4-2
    3-11
    4-1
    3-10
    3-8
  • 原文地址:https://www.cnblogs.com/braink-1400/p/11210935.html
Copyright © 2011-2022 走看看