【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实际上是创建新的委托实例,并把它赋给当前的委托变量”。
感觉自己理解有不对的地方,就先这样吧。