C# 匿名方法和Lambda表达式

一.匿名方法

1.匿名方法的演变

匿名方法是为了简化委托的实现,方便调用委托方法而出现的,同时,匿名方法也是学好lambda表达式的基础。在委托调用的方法中,如果方法只被调用一次,这个时候我们就没有必要创建具名方法,从而用匿名方法更为方便。

下面一段代码是声明并使用了一个名称为Add20的方法(和之前的写法一样)

csharp 复制代码
namespace demo1_0726
{

    public delegate int OtherDel(int n);//声明委托
    internal class Program
    {
        public static int Add20(int x)
        {
            return x + 20;
        }
        static void Main(string[] args)
        {
            OtherDel otherDel = new OtherDel(Add20);
            Console.WriteLine("{0}", otherDel(5));
            Console.WriteLine("{0}", otherDel(6));
            Console.ReadKey();
          
        }
      
    }
}

下面的一段代码使用了匿名方法来替代Add20

csharp 复制代码
namespace demo2_0726
{
    public delegate int OtherDel(int n);//声明委托
    internal class Program
    {
     
        static void Main(string[] args)
        {
            OtherDel otherDel = delegate (int x)
                               {      
                                 return x + 20; 
                                };
            Console.WriteLine("{0}", otherDel(5));
            Console.WriteLine("{0}", otherDel(6));
            Console.ReadKey();

        }

    }
}

2.匿名方法的使用

可以在如下地方使用匿名方法

(1)声明委托变量时作为初始化表达式

(2)组合委托时在赋值语句的右边

(3)为委托增加事件时在赋值语句的右边

3.匿名方法的语法

匿名方法表达式的语法包含如下部分:

csharp 复制代码
//delegate类型关键字
//参数列表,如果语句块没有使用任何参数则可以省略
//语句块,包含了匿名方法的代码
//关键字( 参数列表) { 语句块 }
delegate (Parameters) {ImplementationCode}

1.返回类型

匿名方法不会显示声明返回值。如果委托有void类型的返回值,匿名方法就不能有返回值。

csharp 复制代码
//这里委托类型的返回类型是整形
delegate int OtherDel(int InParam);
static void Main()
{
OtherDel del=delegate(int x)
             {
              return x+20;//返回一个整型值
              };
......              
}

2.参数

除了数组参数,匿名方法的参数列表必须在以下3方面与委托匹配:

参数数量;参数类型及位置;修饰符

以下情况,我们可以使圆括号为空或省略圆括号来简化匿名方法的参数列表(两项同时成立)

1 委托的参数列表不包含任何out参数

2 匿名方法不使用任何参数

举例

csharp 复制代码
namespace demo2_0726
{
    public delegate void OtherDel(int n);//声明委托
    internal class Program
    {
        static void Main(string[] args)
        {
            Program program = new Program();
            //OtherDel otherDel = delegate (int n)//可以写全
             OtherDel otherDel = delegate //也可以省略括号
             {
                program.sum();
                program.subtract();
            };
            otherDel(5);
            Console.ReadKey();
        }
        void sum()
        {
            int n = 4;
            n += 3;
        }
        void subtract()
        {
            int n = 4;
            n -= 2;
        }
    }
}

3.params参数

如果声明委托的参数列表包含了params参数,那么params关键字在匿名方法的参数列表中就会被省略:

csharp 复制代码
delegate void SomeDel(int X,params int[] Y)//在委托声明中使用params关键字
SomeDel mDel=delegate(int X, int[] Y)//在匹配的匿名方法中省略关键字
{
...
};

4.变量和参数的作用域

1 参数以及声明在匿名方法内部的局部变量的作用域限制在实现方法的主体之内.

2 与委托的具名方法不同,匿名方法可以访问它们外围作用域的局部变量和环境,方法中的代码可以访问外围变量并且输出它的值。

二.Lambda表达式

1.Lambda表达式简介

C#2.0引入了匿名方法,C#3.0引入了Lambda表达式,匿名方法演变成Lambda表达式,在使用中我们更希望使用Lambda表达式来替代匿名方法。

2.匿名方法转换为Lambda表达式的步骤

1 删除delegate关键字

2 在参数列表和匿名方法主体之间放lambda运算符=>。lambda运算符读作goes to

csharp 复制代码
Mydel del=delegate(int x)  {return x+1;};//匿名方法
Mydel le1=        (int x)=>{return x+1;};//Lambda表达式

3.简化Lambda表达式

(1) 编译器可以从委托的声明中知道委托参数的类型,因此Lambda表达式允许我们省略类型参数。

带有类型的参数列表称为显示类型

省略类型的参数列表称为隐式类型

(2)如果只有一个隐式类型参数 ,我们可以省略周围的括号。

(3)Lambda表达式允许表达式的主体是语句块或者表达式。如果语句块包含了一个返回语句,我们可以将语句块替换为return关键字后的表达式(即去掉关键字return)。

csharp 复制代码
Mydel del=delegate(int x)  {return x+1;};//匿名方法
Mydel le1=        (int x)=>{return x+1;};//Lambda表达式
Mydel le1=            (x)=>{return x+1;};//省略类型的Lambda表达式
Mydel le1=             x =>{return x+1;};//省略隐式类型周围的括号的Lambda表达式
Mydel le1=             x =>        x+1  ;//去掉关键字return的Lambda表达式

4.Lambda表达式的注意事项

(1) Lambda表达式参数列表中的参数必须在参数数量、类型和位置上与委托相匹配;

(2) 表达式的参数列表中的参数不一定需要包含类型(隐式类型),除非委托有ref或out参数--此时必须注明类型(显示类型)

(3) 如果只有一个隐式类型参数并且是隐式类型的 ,我们可以省略周围的括号。 ,否则必须有括号

(4) 如果没有参数,必须使用一组空的圆括号。

相关推荐
神奇侠202416 分钟前
基于Centos7.X系统端口占用处理
linux·运维·服务器
阿杰同学18 分钟前
如何实现 MySQL 的读写分离?
数据库·mysql
weisian15131 分钟前
Redis篇--应用篇3--数据统计(排行榜,计数器)
数据库·redis·缓存
羊村懒哥33 分钟前
mysql-二进制安装方式
数据库·mysql
言之。36 分钟前
Redis单线程快的原因
数据库·redis·缓存
geovindu1 小时前
python: Oracle Stored Procedure query table
数据库·python·mysql·postgresql·oracle·sqlserver·mssql
工业甲酰苯胺1 小时前
聊一聊 C#线程池 的线程动态注入
java·开发语言·c#
山人在山上1 小时前
arcgis server ip修改后服务异常解决方案
数据库·tcp/ip·arcgis
向宇it1 小时前
【从零开始入门unity游戏开发之——C#篇30】C#常用泛型数据结构类——list<T>列表、`List<T>` 和数组 (`T[]`) 的选择
java·开发语言·数据结构·unity·c#·游戏引擎·list
不剪发的Tony老师2 小时前
SQL实现新年倒计时功能
数据库·sql