匿名方法、Lambda表达和自定义泛型委托以及Func、Action系统泛型委托

1.匿名方法的概念:一个方法没有具体的名称,而只有关键字delegate、方法参数、方法体、这种方法是匿名方法。

匿名方法的好处:将具体方法和委托直接关联在一起,如果我们基于委托只需要一个方法的时候,匿名方法肯定显得简单。

2.Lambda表达式:在C#3.0出现的。使用这种表达的可以更简练的编写代码块。

CalculatorDelegate cal3 = (int a, int b) => { return a + b; };
CalculatorDelegate cal4 = (a, b) => a - b;

【1】Lambad的参数类型可以是明确类型,也可以是推断类型。

【2】如果是推断类型,则参数类型可以由编译根据上下文自动推断出来

【3】运算符=>读作goes to,运算符左边输入参数,右边是表达式或者代码块。

【4】表达式有两种方式:

(input args)=>表达式
(input args)=>{ 语句1;语句2;语句3....}

【5】Lambda表达式和匿名方法的比较:

第一,Lambda本身就是匿名方法。

第二,Lambda表达式不允许指明参数类型,但是匿名方法必须要明确。

第三,Lambda表达式允许单一的表达式或者多条语句组成,而匿名方法不允许单一表达式。

3.自定义泛型委托

【1】为什么要用泛型委托?普通委托在数据类型上的限定是非常严格的,有时候我们的需求变化,可能适应不了,这时候考虑的就是泛型委托。

【2】泛型委托定义:本质上和泛型方法是非常类似的,泛型委托关联的时候可以是具体方法,匿名方法或者Lambda表达式。

【3】试想如果我们有五个参数、六个参数甚至更多的参数,按照目前的思路我们不得不定义很多种这种方法,很麻烦,这时候就要考虑系统泛型委托,所谓系统泛型委托,就是C#.NET为

我们定义好的泛型委托,可以直接拿来用。

4.自定义泛型委托:主要介绍两种,一种是有返回值的Func<T>和一种是没有返回值的Action<T>

Action<T>在多线程中用的非常多。

Func<T>在扩展方法中用的非常多。

结论:泛型委托作为方法参数,实际上传递的是一个具体方法或一个Lambda表达式! (多态一种表现)

a.自定义普通委托和Lambda表达式:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdVancedTest
{
    public class LambdaDemo
    {
        public static void Test()
        {
            //委托关联独立的方法
            CalCulatorDelegate MyCal1 = Add;
            int result1 = MyCal1(10, 20);
            Console.WriteLine("委托关联独立的方法来计算a+b=" + result1);
            //委托关联匿名方法
            CalCulatorDelegate MyCal2 = delegate (int a, int b) { return a + b; };
            int result2 = MyCal2(30, 30);
            Console.WriteLine("通过匿名方法来计算a+b" + result2);
            //将匿名方法简化为Lambda表达式:goes to  参数列表(参数1,参数2....)=>{函数体}
            CalCulatorDelegate MyCal3 = (int a, int b) => 
            {
                Console.WriteLine(100);
                return a + b; 
            };

            //进一步简化:假如方法中只有一行代码,可以省略{}
            CalCulatorDelegate MyCal4 = (a, b) => a + b;
            int result4 = MyCal4(40,50);
            Console.WriteLine("简化Lambda表达式计算a+b="+result4);
            SayHelloDelegate sayHello = (msg) => msg;
            string result5= sayHello("Hello World");
            Console.WriteLine("SayHello委托:"+result5);

            //Lambda表达式允许不指明参数类型,但是匿名方法必须要明确。
            CalCulatorDelegate myCal5 = (a, b) => { return a + b; };
            myCal5(10,12);
        }
        private static int Add(int a, int b)
        {
            return a + b;
        }
    }
    //【1】声明委托
    public delegate int CalCulatorDelegate(int a, int b);
    public delegate string SayHelloDelegate(string msg);
}
复制代码

输出结果为:

委托关联独立的方法来计算a+b=30
通过匿名方法来计算a+b60
简化Lambda表达式计算a+b=90
SayHello委托:Hello World

b.自定义泛型委托

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdVancedTest
{
    public class GenericClass
    {
        public static void Test()
        {
            //范型委托关联具体方法,基于泛型委托,
            MyGenericDelegate<int> myGenericDelegate1 = Add;
            int result1 = myGenericDelegate1(10, 30);
            Console.WriteLine("范型委托关联具体方法:" + result1);

            //泛型委托关联元祖方法
            MyDelegate<string, int, int> myDelegate1 = Mymethod;
            var result2= myDelegate1();

            //使用元组的默认参数名
            var result4 = Mymethod();
            Console.WriteLine(result4.str+"\t"+result4.a+"\t"+result4.b);
            Console.WriteLine(result2.Item1+result2.Item2+result2.Item3);

            //使用元组的自定义参数名
            MyDelegate<string ,int ,int > myDelegate2 = Mymethod;
            var result3 = myDelegate2();
            Console.WriteLine(result3);

            //使用泛型委托:匿名方法
            MyGenericDelegate<int> myGenericDelegate4 = delegate(int a,int b){ return a + b; };
            MyGenericDelegate<double> myGenericDelegate5 = delegate (double a, double b) { return a + b; };

            int result5=myGenericDelegate4(20,30);
            Console.WriteLine(result5);
            double result6 = myGenericDelegate5(20,30);
            Console.WriteLine(result6);

            //使用泛型委托:Lambaa表达式
            MyGenericDelegate<int> myGenericDelegate6 = (a, b) => a + b;
            int result7= myGenericDelegate6(20, 30);
            Console.WriteLine(result7);

            MyGenericDelegate<double> myGenericDelegate7 = (a, b) => a + b;
            double result8= myGenericDelegate7(20, 30);
            Console.WriteLine(result8);
        }
        private static int Add(int a, int b)
        {
            return a + b;
        }
        private static int Sub(int a, int b)
        {
            return a - b;
        }
        //元组C#7.0新操作:元組
        private static (string str, int a, int b) Mymethod()
        {
            return ("C#.NET",4, 5);
        }

    }
    //定义泛型委托
    public delegate T MyGenericDelegate<T>(T param1, T param2);

    public delegate (T1, T2, T3) MyDelegate<T1, T2, T3>();


}
复制代码

输出结果

范型委托关联具体方法:40
C#.NET  4       5
C#.NET45
(C#.NET, 4, 5)
50
50
50
50

c.系统泛型委托

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdVancedTest
{
    public class FuncDemo
    {
        /// <summary>
        /// Func的基本使用: 在扩展方法中用的非常多,最后一个表示返回自类型
        /// </summary>
        /// <returns></returns>
        public static int Test1()
        {
            Func<int, int, int> func1 = Add1;//输入,输入,输出
            int result1 = func1(10, 20);
            //直接使用Lambad表达式,第四个参数表示返回值为string类型
            Func<int, int, int, string> fun3 = (a,b,c) => { return (a + b+c).ToString(); };
            Func<int, int, int> func2 = (a, b) => a + b;
            int result2 = func2(40,40);
            string result3 = fun3(40,40,60);
            Console.WriteLine("------------------------------------------------------------------------");
            Console.WriteLine(result1);//30
            Console.WriteLine(result2);//80
            Console.WriteLine(result3);//140
            return result1;
        }
        private static int Add1(int a,int b) 
        {
            return a + b;
        }
        private static int Mul1(int a, int b)
        {
            return a * b;
        }
        /// <summary>
        /// Func委托的重要使用
        /// </summary>
        /// <returns></returns>
        ///  
       //问题:给定一个数组 { 10, 9, 8, 7, 6, 5, 4, 3, 2 },从数组中指定位置抽取3个数,求和、求积
        public int Test2() 
        {
            //普通方法求和求积
            int[] nums = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
            Sum(nums,0,2);

           return Mul(nums,0,2);
        }

        private int Sum(int[]nums,int From,int To) 
        {
            int sum = 0;
            for (int i=From;i<To;i++) 
            {
                sum += nums[i];
            }
            return sum;
        }

        private int Mul(int[] nums, int From, int To)
        {
            int mul = 1;
            for (int i = From; i < To; i++)
            {
                mul *= nums[i];
            }
            return mul;
        }

        //把Func委托做为参数传递实际传递的是一个具体的方法或者一个Lambda表达式:也是多态的一种表现
        private static int Operation(Func<int,int,int> method,int[]nums,int from,int to) 
        {
            int result = nums[from];
            for (int i=from+1;i<to;i++) 
            {
                //method(result,nums[i]):方法的返回值
                result = method(result, nums[i]);
            }
            return result;
        }

        public static void Test3 () 
        {
            int[] nums = new int [] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
            int result1= Operation(Add1,nums,0,3);//计算加运算
            int result2 = Operation(Mul1,nums,0,3);//计算乘法运算
            Console.WriteLine("返回10+9+8="+result1);
            Console.WriteLine("返回10*9*8="+result2);
        }
    }
}
复制代码

 d.Func<T>委托

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OperationXml
{
    public class A
    {
        bool bDeviceConnected = false;
        public void test()
        {
            Variable.val = new VarRef<object>(() => bDeviceConnected, val => { bDeviceConnected = (bool)val; });
            Console.WriteLine(bDeviceConnected);
            Variable.val.Value = true;
            Console.WriteLine(bDeviceConnected);
        }
    }
    public class VarRef<T>
    {
        public Func<T> _get;
        public Action<T> _set;

        /// <summary>
        /// 传递一个系统泛型委托,实际传递的是一个泛型方法
        /// @get:传递() => bDeviceConnected,获取bDeviceConnected
        /// @set:设置bDeviceConnected的值
        /// </summary>
        public VarRef(Func<T> @get, Action<T> @set)
        {
            _get = @get;
            _set = @set;
        }

        /// <summary>
        /// 属性,对bDeviceConnected进行读和写
        /// </summary>
        public T Value
        {
            get { return _get(); }
            set { _set(value); }
        }

    }
    public  class Variable
    {
        public static VarRef<object> val;
    }
}
复制代码

输出结果

False
True

 

posted @   WellMandala  阅读(146)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示