欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【C#】学习笔记(1) Delegates,Events,Lambda Expressions

程序员文章站 2022-07-05 10:30:48
C#是跟着杨老师的教程走的,在这里感谢一下老师的无私奉献,他的cnblog地址:>cgzl,他的B站地址:>solenovex。 进入正题: Delegate表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。(引用官方文档的英文原话) Represents a delegat ......

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)(委托实例)时,先调用了委托,委托再去调用目标方法。画个图应该很好理解。

【C#】学习笔记(1) Delegates,Events,Lambda Expressions

优点:解耦。

应用:编写插件式的方法

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

  

 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 }

运行结果:

【C#】学习笔记(1) Delegates,Events,Lambda Expressions

画个图分析一下:

【C#】学习笔记(1) Delegates,Events,Lambda Expressions

 

多播委托

  委托按着我自己的理解就是把别人的方法放到我这儿,要用的时候去拿,但是不是在我这儿拿,而是到别人那去。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);
        }
    }
}

输出结果:

【C#】学习笔记(1) Delegates,Events,Lambda Expressions

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

 

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