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

如何从Action委托外部获取其源码文件及行号并提取对应代码

解决Action委托对应源码提取问题

问题核心是当前代码读取的是整个PrintSourceCode调用的行,需要从调用行中定位并提取lambda表达式(即Action对应的代码块)。由于匿名委托的MethodInfo指向编译器生成的内部方法,无法直接获取源码位置,只能通过调用点的源码文件解析lambda块。

修改后的实现代码

using System.Text;
using System.Text.RegularExpressions;

static void PrintSourceCode(Action action)
{
    action();

    var frame = new StackFrame(1, true);
    var startLineNumber = frame.GetFileLineNumber();
    var fileName = frame.GetFileName();
    if (string.IsNullOrEmpty(fileName))
    {
        Console.WriteLine("无法获取源码文件");
        return;
    }

    var lines = File.ReadAllLines(fileName);
    var result = new StringBuilder();
    int braceCount = 0;
    bool insideLambda = false;

    for (int currLineIndex = startLineNumber - 1; currLineIndex < lines.Length; currLineIndex++)
    {
        var currentLine = lines[currLineIndex];
        var trimmedLine = currentLine.Trim();

        // 定位lambda的起始标记
        if (!insideLambda && trimmedLine.Contains("() =>"))
        {
            // 检查当前行是否包含起始大括号
            var braceMatch = Regex.Match(currentLine, @"\{");
            if (braceMatch.Success)
            {
                insideLambda = true;
                braceCount++;
                // 添加从大括号开始的内容
                result.AppendLine(currentLine.Substring(braceMatch.Index));
            }
            continue;
        }

        if (insideLambda)
        {
            result.AppendLine(currentLine);
            // 统计大括号数量
            foreach (char c in currentLine)
            {
                if (c == '{') braceCount++;
                else if (c == '}') braceCount--;
            }

            // 当大括号闭合时退出循环
            if (braceCount == 0)
            {
                break;
            }
        }
    }

    Console.WriteLine(result.ToString().TrimStart());
}

关键逻辑说明

  • 定位lambda起始:从调用PrintSourceCode的行开始,找到包含() =>的行,定位lambda的起始大括号。
  • 跟踪大括号层级:通过统计{和}的数量,处理可能的嵌套大括号,确保找到lambda块的闭合大括号。
  • 提取目标内容:只保留lambda块内部的代码(包括前后大括号),过滤掉外部的PrintSourceCode调用代码。

关于获取Action文件/行信息的说明

直接从Action委托本身无法获取对应的源码文件和行号,因为匿名委托会被编译器编译为一个内部匿名方法,其MethodInfo不包含用户源码的位置信息。必须通过调用点的StackFrame获取源码文件路径,再解析lambda块的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 01:57:37