【C#】学习笔记(1) Delegates,Events,Lambda Expressions
c#是跟着杨老师的教程走的,在这里感谢一下老师的无私奉献,他的cnblog地址:>,他的b站地址:>。
进入正题:
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实际上是创建新的委托实例,并把它赋给当前的委托变量”。
感觉自己理解有不对的地方,就先这样吧。