【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实际上是创建新的委托实例,并把它赋给当前的委托变量”。

 

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

posted @ 2019-07-19 01:23 BrainK_1400 阅读(...) 评论(...) 编辑 收藏