You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译器如何正确转换含闭包的C# LeakingClosure代码?

编译器生成的闭包类与方法实现

你遇到的编译错误核心是捕获变量的类型不匹配——Average()返回double,所以闭包类中需要用double类型存储importantStatistic,而非和GetNumbers()返回的int混淆。以下是编译器针对该场景生成的等效代码:

完整模拟代码(含你补充的类)

using System;
using System.Collections.Generic;
using System.Linq;

// 你补充的CheapNumberGenerator类
public class CheapNumberGenerator
{
    public IEnumerable<int> GetNumbers()
    {
        for (int i = 1; i <= 10; i++)
            yield return i;
    }
}

// 你补充的ResourceHogFilter类(示例实现)
public class ResourceHogFilter
{
    public static IEnumerable<int> Filter(IEnumerable<int> source, double threshold)
    {
        foreach (var num in source)
            if (num > threshold)
                yield return num;
    }
}

public class ClosureDemo
{
    // 原LeakingClosure方法
    public static void LeakingClosure()
    {
        var results = new CheapNumberGenerator();
        double importantStatistic = results.GetNumbers().Average();

        var filtered = from n in results.GetNumbers()
                       where n > importantStatistic
                       select n;

        // 触发查询执行
        foreach (var num in filtered)
            Console.WriteLine(num);
    }

    // ------------------------------
    // 编译器生成的等效代码(手动模拟)
    // ------------------------------

    // 编译器自动生成的闭包类:用于捕获外部变量
    private sealed class COMPILER_Closure
    {
        // 字段类型为double,匹配Average()的返回值
        public double importantStatistic;

        // 编译器生成的lambda对应方法
        public bool COMPILER_FilterMethod(int n)
        {
            // int与double的比较是合法的隐式转换
            return n > importantStatistic;
        }
    }

    // 编译器转换后的LeakingClosure方法
    public static void COMPILER_LeakingClosure()
    {
        COMPILER_Closure closureInstance = new COMPILER_Closure();
        var results = new CheapNumberGenerator();
        
        // 将外部变量赋值给闭包类的字段
        closureInstance.importantStatistic = results.GetNumbers().Average();

        // 将查询表达式转为方法调用,绑定闭包类的方法作为委托
        var filtered = results.GetNumbers().Where(new Func<int, bool>(closureInstance.COMPILER_FilterMethod));

        // 触发查询执行
        foreach (var num in filtered)
            Console.WriteLine(num);
    }
}

关键说明

  1. 类型匹配:闭包类中存储importantStatistic的字段类型为double,完全匹配Average()的返回类型,解决了你遇到的类型不匹配错误。
  2. 委托绑定:编译器生成的COMPILER_FilterMethod接收int类型参数,与闭包类的double字段比较——C#允许int和double的隐式比较,因此不会有编译问题。
  3. 闭包捕获逻辑:外部变量被转移到闭包类的实例字段中,委托通过闭包类实例访问该字段,实现了对变量的捕获。

内容的提问来源于stack exchange,提问作者na_sacc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 05:24:30