CodeGym /课程 /C# SELF /本地函数

本地函数

C# SELF
第 11 级 , 课程 4
可用

1. 入门

每个程序员都懂:函数(或者叫方法)其实就是任何应用的“主力干活的家伙”。它们帮我们把代码结构化、复用逻辑,不至于在无尽的复制粘贴里迷失。到现在为止,你用过的所有函数,都是在类或者结构体的主体里“并排”存在的。

但想象下,如果你有个很大的函数,里面有一小段逻辑,想单独拎出来,但又不想让整个项目都能看到它。比如说,在某个方法里用到的辅助计算,别的地方根本用不到。

这种时候,本地函数就派上用场了。

本地函数,就是在另一个函数(方法、构造函数、属性,甚至另一个本地函数)里面声明的函数。这种本地函数只对“父亲”可见,别的地方都看不到。

本地函数的语法


void MainMethod()
{
    Console.WriteLine("开始主方法。");            // Start of the main method.
    int result = InnerSum(5, 7);                              // 调用本地函数InnerSum(内部求和)
    Console.WriteLine($"本地函数结果: {result}");    // 结果 local function: {result}

    // 本地函数直接在MainMethod里声明
    
  
int InnerSum(int a, int b) // 本地函数:两个数求和 { return a + b; // 返回a和b的和 }
}

在这个例子里,InnerSum函数直接在MainMethod方法里声明。它在主方法外面完全不可见——完全没门!就像一条只有你俩知道的秘密指令。

2. 怎么声明和用本地函数

基本规则

  • 本地函数可以在:方法、构造函数、属性、操作符,甚至另一个本地函数里声明!
  • 本地函数只在自己的作用域(scope)里可见。
  • 本地函数可以在父函数里声明前或声明后调用(C#会提前分析)。

例子:计算平均分


// 主函数:打印平均分
void PrintAverageScore(int[] scores)
{
    if (scores.Length == 0)
    {
        Console.WriteLine("没有分数可计算。"); // No scores to calculate.
        return;
    }

    double average = CalculateAverage(scores);
    Console.WriteLine($"平均分: {average:0.00}"); // Average score

    // 本地函数:计算平均值
    
  
double CalculateAverage(int[] arr) { int sum = 0; foreach (var score in arr) sum += score; return (double)sum / arr.Length; // 返回平均值 }
} // 调用函数: int[] myScores = { 5, 4, 3, 4, 5 }; PrintAverageScore(myScores); // 输出: 平均分: 4.20

看到没,超方便吧?PrintAverageScore外面的人根本用不了它的内部逻辑——本地函数CalculateAverage。这种写法让代码更有条理,也不会把全局命名空间搞乱,塞一堆辅助方法进去。

3. 本地函数和作用域(scope)

本地函数最大的特点——它的作用域只在“父方法”里。这种行为能防止类里被一堆只用一次的小方法搞得乱七八糟。


+-----------------+
|   类方法        |
|    void Foo()   |
|                 |
|   +-----------+ |
|   |  本地函数 | |
|   |           | |
|   +-----------+ |
+-----------------+
本地函数只存在于声明它的方法内部

本地函数存在于声明它的方法内部。你要是想在外面调用它,就像打一个你根本没有的秘密电话一样,根本不可能。

如果你不小心在父方法外面调用本地函数,会报编译错误:名字 '...' 在当前上下文不存在

本地函数能看到父方法的变量

本地函数可以访问父方法里的所有变量——这就是它的超能力!


void ShowStudent(string name, int age)
{
    string message = BuildMessage();
    Console.WriteLine(message);

    // 本地函数用到了"name"和"age"变量
    
  
string BuildMessage() { return $"姓名: { name}, 年龄: { age}"; }
}

这样写代码不仅更短,还更清爽。不用每次都传一堆参数——本地函数能“看到”父方法里的一切。

4. 循环和条件里的本地函数

本地函数可以在任何嵌套层级声明——甚至在循环或条件分支里:


void ProcessNumbers(int[] numbers)
{
    foreach (int number in numbers)
    {
        if (number % 2 == 0)
        {
            Console.WriteLine($"{number} —— 偶数");
            PrintEvenMessage();
        }
        else
        {
            Console.WriteLine($"{number} —— 奇数");
        }

        
  
void PrintEvenMessage() { Console.WriteLine("这是个偶数,恭喜!"); }
} }

不过这种写法很容易让代码变得难读,尤其是本地函数太多或者太长的时候。别滥用,但知道有这招还是很有用的。

本地函数 vs 普通私有方法

对比项 本地函数 类的私有方法
作用域 只有父函数能用 整个类都能用
能否访问父变量 可以 不行(只能通过参数)
可读性提升 一般
复用潜力
可测试性 难测 容易测

5. 常见错误和实现细节

错误1:拼写错或漏声明本地函数。
如果你调用本地函数时名字写错或者忘了声明,编译器会报CS0103CS0128,代码根本编译不过去。

错误2:修改被捕获的变量(closure)。
如果本地函数改了外部方法的变量,结果可能完全不是你想的——被捕获的变量有时像副本,有时像引用,改了会影响逻辑。

错误3:忽略IDE关于私有方法转本地函数的提示。
如果你在类里留了一堆没必要的私有方法,而IDE(比如Rider)建议你把它们变成本地函数,结果代码很快就会堆满“垃圾”,可读性变差。

错误4:本地函数嵌套太深。
嵌套层级太多的本地函数让代码难懂又难调试。简洁才是王道,维护起来才舒服。

2
任务
C# SELF, 第 11 级, 课程 4
已锁定
使用本地函数计算两个数字的和
使用本地函数计算两个数字的和
2
任务
C# SELF, 第 11 级, 课程 4
已锁定
用于判断数字奇偶性的本地函数
用于判断数字奇偶性的本地函数
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION