首页 > 其他分享 >委托、Lambda表达式、事件

委托、Lambda表达式、事件

时间:2022-11-23 13:34:36浏览次数:36  
标签:string 委托 int void static public 表达式 Lambda

委托:

  把方法当作参数进行传递。委托是一个类型,这个类型可以赋值一个方法的引用。(一个方法的引用可以赋值给这个委托类型)

定义委托:<访问修饰符> delegate 返回值 委托名称(<参数列表>);

使用委托:委托名称 委托类型变量 = 静态方法名 / 委托名称 委托类型变量 = 实例方法 

class Program
    {
        public delegate void IntMethod(int x); //定义委托

        delegate string GetAString();

        static void Main(string[] args)
        {    //使用委托
            IntMethod intMethod = null;
            //委托类型可以引用其它方法,设置为null表示没有引用任何方法
            intMethod = IntMethodTest;//方法当作参数传递,委托可以指向任何方法(实例方法/静态方法等)
            intMethod(100000); //通过委托调用方法
            
            //实例对象赋值方法一
            int i = 123456;
            GetAString getAString = i.ToString; //把方法赋值时不能加(),加()时调用它  i.ToString自身转换为字符串
            //实例对象赋值方法二
            GetAString getAStringy = new GetAString(y.ToString);//new GetAString()无法为空
            Console.WriteLine(getAString());
        }
        public static void IntMethodTest(int x)
        {
            Console.WriteLine("IntMethod的test" + x);
        }
    }
IntMethod的test100000
123456
333444555

 委托数组以及把委托声明的变量当作参数传递

class MathOp
    {
        public static double MultiplayByTwo(double value)
        {
            return value * 2;
        }
        public static double Square(double value)
        {
            return value * value;
        }
    }
//调用
    public delegate double DoubleOpDelegate(double x); //可以指向返回值为double类型的方法
        static void Main(string[] args)
        {
            //声明一个委托类型的数组
            DoubleOpDelegate[] operas = { MathOp.MultiplayByTwo, MathOp.Square };
            foreach(DoubleOpDelegate op in operas)//遍历数组
            {
                //op相当于委托类型的变量,指向数组中的每个元素
                //  Console.WriteLine(op(3));
                ProcessAndDisplay(op, 4);
            }
        }
        //把委托声明的变量当作参数传递
        static void ProcessAndDisplay(DoubleOpDelegate op,double value)
        {
            double result = op(value);
            Console.WriteLine("Result:" + result);
        }
Result:8
Result:16

 Action委托和Func委托(系统自带 )

1)Action委托:用于返回值为void类型

Action:无参数无返回值

Action<int T>:参数类型为int型,无返回值

Action<int T,int T........>:参数类型为int型,无返回值

public static void Sums(int x,double y)
        {
            Console.WriteLine("和:" + (x + y));
        }
        static void Main(string[] args)
        {
            Action<int, double> action = Sums;
            action(2, 4.6);
        }
和:6.6

2)Func委托:用于有返回值的情况

Func<int T,double T,string> :参数类型为int,double,返回值类型为string 

public static String Test(int x,double y)
        {
            return "happy" + x + y;
        }
        static void Main(string[] args)
        {
            Func<int, double, string> f = Test;
            Console.WriteLine( f(3, 1.8));
        }
happy31.8

多播委托

  委托可以包含多个方法的调用,这种委托叫做多播委托。使用多播委托可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果。返回类型为void。

class Program
    {
        public static void Test1()
        {
            Console.WriteLine("test123");
        }
        public static void Test2()
        {
            Console.WriteLine("test456");
        }
        static void Main(string[] args)
        {
            Action action = Test1;
            action();               // test123

            action += Test2; //此时action既指向test1又指向test2,相当于一个集合
            action();              //test123 test456

            //获取委托集合
            Delegate[] delegates = action.GetInvocationList();
            foreach(Delegate d in delegates) //遍历集合
            {
                d.DynamicInvoke();//动态调用里面的方法      //test123 test456
            }
        }
    }

test123
test123
test456
test123
test456

匿名方法和Lambda表达式

1)使用委托,先定义一个方法,然后把方法给委托的实例。

2)使用委托,使用匿名方法(方法没有名字)

使用匿名方法的地方:某个方法使用到的地方很少,单独定义一个方法再赋值给一个委托的话,较为麻烦。使用匿名方法的话可以减少代码量和复杂性。

1)定义方法:

class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> func = Sum;
            int result = func(19, 3);
            Console.WriteLine(result);
        }

        public static  int Sum(int a, int b)
        {
            return a + b;
        }
    }

2)匿名方法:

class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> func = delegate (int a, int b)
              {
                  return a + b;
              };
            int result = func(20, 10);
            Console.WriteLine(result);
        }
    }

 Lambda表达式:匿名方法简写的表达式

当Lambda表达式只有一条语句的时候,可以省略括号和return语句。多行语句需要加括号和return语句。

  Func<int, int, int> func = delegate (int a, int b)
   {
           return a + b;
   };

第一步:Func<int, int, int> func =  (int a, int b)
              {
                  return a + b;
              };

第二步:Func<int, int, int> func =  ( a,  b) => { return a + b; };

第三步:Func<int, int, int> func =  ( a,  b) =>  a + b;

只有一个参数时,不需要写括号:Func<double, double> square = x => x * x;

Lambda表达式可以访问外部变量:

int a = 5;

Func<int, int> func = x => x + a;

方法的结果,不但受到参数的控制,还受到外部变量的控制,结果不可控。

事件

“工具人的操作,下楼后可以给懒人东西。懒人把要带的东西委托给工具人,工具人在下来后调用委托。”

未加事件前:

工具人:

    delegate void DownStairDelegate();
    class ToolMan
    {
        public string name { get; private set; }
        //声明委托
        public DownStairDelegate downStairDelegate = null;
        public ToolMan(string name)
        {
            this.name = name;
        }
        public void DownStair()
        {
            Console.WriteLine("工具人" + name + "下楼了");
            if (downStairDelegate != null)
            {
                downStairDelegate();
            }
        }
    }

懒人:

class LazyMan
    {
        public string name { get; private set; }
        public LazyMan(string name)
        {
            this.name = name;
        }
        public void GetFood()
        {
            Console.WriteLine("给" + name + "取外卖");
        }
        public void GetPackage()
        {
            Console.WriteLine("给" + name + "取快递");
        }
    }

操作:

class Program
    {
        static void Main(string[] args)
        {
            ToolMan toolMan = new ToolMan("小明");
            LazyMan lazyMan1 = new LazyMan("张三");
            LazyMan lazyMan2 = new LazyMan("李四");
            LazyMan lazyMan3 = new LazyMan("王五");

            toolMan.downStairDelegate += lazyMan1.GetFood;
            toolMan.downStairDelegate += lazyMan2.GetPackage;
            toolMan.downStairDelegate += lazyMan1.GetFood;
            
            toolMan.DownStair();
            
            //可以在列表中减去必做项
            toolMan.downStairDelegate -= lazyMan1.GetFood;
            toolMan.DownStair();
            
            //其他人可以删除原本的列表(使用事件可以解决)
            toolMan.downStairDelegate = lazyMan1.GetFood;
            toolMan.DownStair();
            
            //工具人不下楼,也可以触发委托。消息发出去,但是实际上没有执行。
            toolMan.downStairDelegate(); //(使用事件可以解决)
        }
    }

 触发只能由工具人触发,不让其在外部触发。其它人无法发布消息,只能订阅消息。

解决这两个问题可以通过事件,在使用委托前添加event.

public event DownStairDelegate downStairDelegate = null;

事件是受限制的委托。

其他人在使用委托时只能 += / -= 不能使用直接赋值 = 。

事件只能在内部触发,不能在外部调用。

标签:string,委托,int,void,static,public,表达式,Lambda
From: https://www.cnblogs.com/Joyce-mi7/p/16914696.html

相关文章

  • 7-2 栈实现表达式求值
    使用键盘输入数学表达式(含数字,四种运算符+、-、、/和小括号,其中运算数都是一位数(0~9)),将数学表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。输入格式:输......
  • error:当没有用 EXISTS 引入子查询时,在选择列表中只能指定一个表达式
    --报错代码selecttop3* fromemp whereempnonotin(selecttop3*fromemporderbysaldesc) orderbysaldesc错误原因:如果要用in,后面SELECT必须能只......
  • 正则表达式
    正则表达式-在Java中,我们经常需要验证一些字符串,例如:年龄必须是2位的数字、用户名必须是8位长度而且只能包含大小写字母、数字等。正则表达式就是用来验证各种字符串的规......
  • 正则表达式
    1、?前面的字符可有可无xxp?xxxxp2、*前面的字符可出现0~N次xx*pxpxxpxxxp3、+前面的字符可出现1~N次xx+pxxpxxxp4、{}前面的字符可出现......
  • Java 用Lambda实现一个通用的制造者工具
    在我们日常开发中,虽然是用了lombok在实体类中已经帮我们省了get、set方法,但是在公司的项目中,还是经常会出现new一个对象然后一个个的给它set值的情况,太丑了,如下图List<St......
  • 132令非终结符B表示布尔表达式,为B设置两个继承属性 true和 false。B.true是一个地址,地
      关键:true和false为继承属性,语义动作必须出现在非终结符的右边   ......
  • 三元表达式
    条件测试简称条件?号前面是条件测试:号前面是条件成立执行:号后面是条件不成立执行leta=true//如果a为true就显示<view>1</view>//如果a为false就显示<view>0</view><vie......
  • MyBatisPlus之lambdaChainWrapper
    /***通过老科室主键查询对照**@return*/publicDepartmentMappinggetDepartmentMappingByOldId(LongoldId){DepartmentMappin......
  • Python中除了lambda函数能实现一句话程序,还有什么方式能够实现呢?
    引言我们都知道python中使用lambda函数能够实现一句话程序,一句话能实现复杂功能,是一件多么炫酷的事情.但也是有利有弊的,至少一句话代码虽然简洁,但可读性不好,毕竟现实中......
  • 基础代码-计算后缀表达式
    问题E:计算后缀表达式时间限制:1Sec  内存限制:128MB题目描述后缀表达式是将运算符置于两个运算对象之后的一种表达方法,例如“3+4”用写成后缀表达式后就......