【C#进阶】C# 匿名方法

序号 系列文章
18 【C#进阶】C# 事件
19 【C#进阶】C# 集合类
20 【C#进阶】C# 泛型

文章目录

  • 前言
  • 1、什么是匿名方法?
  • 2、delegate 运算符
  • 3、Lambda 表达式
    • 3.1、Lambda 表达式的自然类型
    • 3.2、Lambda 表达式的显示返回类型
  • 4、关于匿名方法的总结
  • 结语

前言

hello大家好啊,我是哈桑c,本文为大家介绍 C# 中的匿名方法。


1、什么是匿名方法?

匿名方法顾名思义就是这类方法的特点是不需要特别去定义函数的名字的。一般我们需要一个函数,但又不想花时间去命名它的时候,就可以使用匿名方法。在 C# 中, 匿名方法通常表现为使用 delegate 运算符和 Lambda 表达式。

代码示例:(简单演示)

delegate 运算符:

public class SampleAnonymousMethod
{
    static void Main(string[] args)
    {
        Func<int, int, int> sum = delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(11,22));  
        
        //输出:33
    }
}

Lambda 表达式:

public class SampleAnonymousMethod
{
    static void Main(string[] args)
    {
        Func<int, int> square = x => x * x;
        Console.WriteLine(square(5));
        
        // 输出:25
    }
}

2、delegate 运算符

delegate 运算符创建一个可以转换为委托类型的匿名方法。 匿名方法可以转换为System.Action 和 System.Func 等类型,同时指定自定义的参数列表。

代码示例:

Func<string, string, string> hello = delegate (string s1, string s2) { return s1 + s2; };
Console.WriteLine(hello("hello,", "world"));  

运行结果:
【C#进阶】C# 匿名方法_第1张图片
可以看到,即使是一个没有方法名只有方法体的匿名方法也可以正常输出运算结果。

使用 delegate 运算符时,也可以直接省略参数列表,表示创建的匿名方法可以转换为具有任何参数列表的委托类型。

代码示例:

Action greet = delegate { Console.WriteLine("你好!"); };
greet();

Action<int, double> introduce = delegate { Console.WriteLine("这就是世界!"); };
introduce(7, 2.5);

运行结果:
【C#进阶】C# 匿名方法_第2张图片
在上例中可以看到,即可没有声明参数列表的匿名方法在转换为有参数列表的 Action 方法时也可以正常运行。

从 C# 9.0版本开始,可以使用弃元1指定该方法不使用的两个或更多个匿名方法的输入参数。当方法中返回的结果没有任何作用时,就可以使用弃元。

代码示例:

Func<int, int, int> constant = delegate (int _, int _) { return 42; };
Console.WriteLine(constant(3, 4));  

// 输出:42

3、Lambda 表达式

Lambda 表达式的本质也是匿名方法。Lambda 表达式提供了一种简洁和富有表现力的方式来创建匿名函数,可以使用 => 运算符来构造 Lambda 表达式。

Lambda 表达式的定义语法可以总结为如下:

(input-parameters) => { <sequence-of-statements> }
  • input-parameters: 表示输入参数,也即参数列表。
  • sequence-of-statements: 表示表达式语句序列部分。

若要创建 Lambda 表达式,需要在 Lambda 运算符左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块。当语句序列部分有且仅有一个表达式时,可以省略大括号的书写。

任何 Lambda 表达式都可以转换为对应的委托类型。 Lambda 表达式可以转换的委托类型由其参数和返回值的类型定义。如果 lambda 表达式不返回值,则可以将其转换为 Action 委托类型之一;否则,可将其转换为 Func 委托类型之一。

代码示例:

// lambda 表达式不返回值,可以将其转换为 Action 委托类型之一 
Action greet = () => { Console.WriteLine("Hello,World"); };   
greet();

// 输出:"Hello,World"
// lambda 表达式返回值,可以转换为 Func 委托类型之一 
Func<int, int> square = x => x * x;
Console.WriteLine(square(5));

// 输出:25

演示 Lambda 表达式有参和无参的两种写法。

有参写法:

Action<string> greet = name => Console.WriteLine($"Hello {name}!";
greet("World");

// 输出: Hello World!  

编写 lambda 时,通常不必为输入参数指定类型,因为编译器可以根据 lambda 主体、参数类型以及 C# 语言规范中描述的其他因素来推断类型。

无参写法:

Action greet = () => Console.WriteLine($"Hello World!");
greet(); 

// 输出: Hello World!  

3.1、Lambda 表达式的自然类型

从 C# 10开始,Lambda 表达式可能具有自然类型,也就是编译器可以根据 Lambda 表达式推断委托类型。但是并非所有 Lambda 表达式都有自然类型,有时候编译器无法推断 s 的参数类型。这时我们就必须声明 Lambda 表达式的类型了。

代码示例:

object parse = (string s) => int.Parse(s); 
Console.WriteLine(parse.GetType());

运行结果:
【C#进阶】C# 匿名方法_第3张图片
从上例中可以看到,编译器顺利推断出了匿名方法的类型 System.Func ,而无需声明具体的方法类型。

代码示例:

var parse = s => int.Parse(s); // ERROR: Not enough type info in the lambda

代码效果:
【C#进阶】C# 匿名方法_第4张图片

3.2、Lambda 表达式的显示返回类型

从 C# 10 开始,使用 Lambda 表达式时可以在输入参数前面显示指定表达式的返回类型,同时必须使用括号把输入参数括起来。

代码示例:

var judge = int (bool b) => b ? 1 : 2;      // int表示返回类型为整数类型
Console.WriteLine(judge(true));

// 输出:1

4、关于匿名方法的总结

匿名方法的优点:

  • 简洁性: 匿名方法可以用更少的代码实现相同的功能。减少代码的复杂性和冗余性,使代码更加简洁。
  • 灵活性: 匿名方法可以作为参数传递给方法,也可以当作返回值返回。
  • 可读性: 匿名方法代码量更少,可以使代码更加清晰易懂,可读性较高。
  • 性能高: 使用 Lambda 表达式可以轻松创建包含异步处理的表达式和语句。

匿名方法的缺点:

  • 重用性低: 匿名方法不能在其它地方进行调用,因此重用性较低。

什么时候需要使用匿名方法:

  • 临时需要一个方法,而且方法使用次数较少。
  • 方法的代码量很少,使用匿名方法显得更加简洁。

点击了解更多匿名方法的使用。


结语

以上就是 C# 匿名方法的介绍啦,希望对大家有所帮助。感谢大家的点赞、收藏、评论和关注。


  1. 弃元: 是一种在应用程序代码中人为取消使用的占位符变量。 ↩︎

你可能感兴趣的:(C#/.NET系列文章,c#,开发语言,.net,微软,.netcore)