C# 中的本地函数

今天我们来聊一聊 C# 中的本地函数。本地函数是从 C# 7.0 开始引入,并在 C# 8.0 和 C# 9.0 中加以完善的。引入本地函数的原因我们来看一下微软 C# 语言首席设计师 Mads Torgersen 的一段话:Mads Torgersen:我们认为这个场景是有用的 —— 您需要一个辅助函数。 您仅能在单个函数中使用它,并且它可能使用包含在该函数作用域内的变量和类型参数。 另一方面,与 lambda 不同,您不需要将其作为第一类对象,因此您不必关心为它提供一个委托类型并分配一个实际的
摘要由CSDN通过智能技术生成

今天我们来聊一聊 C# 中的本地函数。本地函数是从 C# 7.0 开始引入,并在 C# 8.0 和 C# 9.0 中加以完善的。

引入本地函数的原因

我们来看一下微软 C# 语言首席设计师 Mads Torgersen 的一段话:

Mads Torgersen:
我们认为这个场景是有用的 —— 您需要一个辅助函数。 您仅能在单个函数中使用它,并且它可能使用包含在该函数作用域内的变量和类型参数。 另一方面,与 lambda 不同,您不需要将其作为第一类对象,因此您不必关心为它提供一个委托类型并分配一个实际的委托对象。 另外,您可能希望它是递归的或泛型的,或者将其作为迭代器实现。1

正是 Mads Torgersen 所说的这个原因,让 C# 语言团队添加了对本地函数的支持。
本人在近期的项目中多次用到本地函数,发现它比使用委托加 Lambda 表达式的写法更加方便和清晰。

本地函数是什么

用最简单的大白话来说,本地函数就是方法中的方法,是不是一下子就理解了?不过,这样理解本地函数难免有点片面和肤浅。

我们来看一下官方对本地函数的定义:

本地函数是一种嵌套在另一个成员中的私有方法,仅能从包含它的成员中调用它。 2

定义中点出了三个重点:

  1. 本地函数是私有方法
  2. 本地函数是嵌套在另一成员中的方法。
  3. 只能从定义该本地函数的成员中调用它,其它位置都不可以。

其中,可以声明和调用本地函数的成员有以下几种:

  • 方法,尤其是迭代器方法和异步方法
  • 构造函数
  • 属性访问器
  • 事件访问器
  • 匿名方法
  • Lambda 表达式
  • 析构函数
  • 其它本地函数

举个简单的示例,在方法 M 中定义一个本地函数 add

public class C
{
   
    public void M()
    {
   
        int result = add(100, 200);
        // 本地函数 add
        int add(int a, int b) {
    return a + b; }
    }
}

本地函数都是私有的,目前可用的修饰符只有 asyncunsafestatic(静态本地函数无法访问局部变量和实例成员) 和 extern 四种。在包含成员中定义的所有本地变量和其方法参数都可在非静态的本地函数中访问。本地函数可以声明在其包含成员中的任意位置,但通常的习惯是声明在其包含成员的最后位置(即结束 } 之前)。

本地函数与 Lambda 表达式的比较

本地函数和我们熟知的 Lambda 表达式 3非常相似,比如上面示例中的本地函数,我们可以使用 Lambda 表达式实现如下:

public void M()
{
   
    // Lambda 表达式
    Func<int, int, int> add = (int a, int b) => a + b;
    int result = add(100, 200);
}

如此看来,似乎选择使用 Lambda 表达式还是本地函数只是编码风格和个人偏好问题。但是,应该注意到,使用它们的时机和条件其实是存在很大差异的。

我们来看一下获取斐波那契数列第 n 项的例子,其实现包含递归调用。

// 使用本地函数的版本
public static uint LocFunFibonacci(uint n)
{
   
    return Fibonacci(n);

    uint Fibonacci(uint num)
    {
   
        if (num == 0) return 0;
        if (num == 1) return 1;
        return checked(Fibonacci(num - 2) + Fibonacci(num - 1));
    }
}
// 使用 Lambda 表达式的版本
public static uint LambdaFibonacci(uint n)
{
   
    Func<uint, uint> Fibonacci = null; //这里必须明确赋值
    Fibonacci = num => {
   
        if (num == 0) return 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值