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

如何在C#项目中实现获取指定方法所有调用参数的函数?

问题需求

需要实现一个函数,获取项目中MethodA(string a)所有调用的参数值。比如存在以下调用:

MethodA("1");
MethodA("2");

调用GetAllMethodArguments("MethodA")应返回["1", "2"]。尝试用反射实现,但没能成功。

为什么反射搞不定这事

反射的核心是读取程序集的元数据,比如方法的名称、参数类型、返回值类型这些定义,但它没法追踪方法调用时的动态参数值:

  • 反射没有能力回溯已经执行过的调用的参数
  • 也没法主动监听方法的所有调用并捕获参数
    简单说,反射管的是"方法是什么样的",不是"方法被怎么调用的"。
两种可行的实现方案

方案1:在目标方法内部埋点记录

这是最直接的运行时方案,修改MethodA,每次调用时把参数存到全局集合里,GetAllMethodArguments直接读取这个集合:

// 全局存储MethodA的调用参数,用静态集合保证生命周期一致
private static readonly List<string> _methodAArgs = new List<string>();

public static void MethodA(string a)
{
    // 先记录参数
    _methodAArgs.Add(a);
    // 原来的方法逻辑
    // ...
}

public static List<string> GetAllMethodArguments(string methodName)
{
    if (methodName == nameof(MethodA))
    {
        // 返回副本,避免外部修改内部集合
        return new List<string>(_methodAArgs);
    }
    return new List<string>();
}

方案2:静态代码分析(编译期提取)

如果不能修改MethodA的代码,可以用.NET的Roslyn编译器API做静态代码分析,遍历项目源码,解析语法树找到所有MethodA的调用,提取字面量参数:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;
using System.IO;

public static List<string> GetAllMethodArgumentsFromSource(string projectRootPath, string targetMethodName)
{
    var collectedArgs = new List<string>();

    // 遍历项目下所有C#源码文件
    foreach (var csFile in Directory.EnumerateFiles(projectRootPath, "*.cs", SearchOption.AllDirectories))
    {
        var codeText = File.ReadAllText(csFile);
        var syntaxTree = CSharpSyntaxTree.ParseText(codeText);
        var rootNode = syntaxTree.GetRoot();

        // 找所有方法调用节点
        var invocations = rootNode.DescendantNodes().OfType<InvocationExpressionSyntax>();
        foreach (var invocation in invocations)
        {
            // 判断是不是目标方法的调用
            if (invocation.Expression is IdentifierNameSyntax methodId && methodId.Identifier.Text == targetMethodName)
            {
                // 取第一个参数(对应MethodA的string参数)
                var firstArg = invocation.ArgumentList.Arguments.FirstOrDefault();
                if (firstArg?.Expression is LiteralExpressionSyntax stringLiteral && stringLiteral.Kind() == SyntaxKind.StringLiteralExpression)
                {
                    collectedArgs.Add(stringLiteral.Token.ValueText);
                }
            }
        }
    }

    return collectedArgs;
}

注意:这个方案只能提取编译期的字符串字面量参数,如果调用时传入的是变量、表达式或者运行时生成的值,是没法拿到实际运行值的,只能拿到代码里的表达式内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:22:40