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

如何检查C#文件使用的类与方法?如何安全扫描插件代码限制API调用?

针对你的两个C#相关问题,我来分享下实际开发中常用的解决方案,都是经过项目验证的靠谱方法:

问题1:检查指定C#文件中使用的类与方法

最靠谱的方式是利用微软官方的Roslyn编译器服务,它能直接解析C#源码的语法树和语义信息,精准识别类、方法的引用,比正则表达式或者简单字符串匹配靠谱得多。

  • Roslyn语法/语义分析实现
    你可以通过编写代码遍历源码的语法节点,或者借助SemanticModel获取符号的具体类型信息,区分定义和引用,还能处理using别名、泛型等复杂场景:

    // 示例代码:解析C#文件并输出所有引用的类和方法
    var sourceCode = File.ReadAllText("TargetFile.cs");
    var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);
    
    // 创建临时编译上下文,添加必要的程序集引用
    var compilation = CSharpCompilation.Create("TempAnalysisCompilation")
        .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
        .AddSyntaxTrees(syntaxTree);
    
    var semanticModel = compilation.GetSemanticModel(syntaxTree);
    // 遍历所有标识符节点,获取对应的符号信息
    var identifierNodes = syntaxTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>();
    
    foreach (var node in identifierNodes)
    {
        var symbol = semanticModel.GetSymbolInfo(node).Symbol;
        if (symbol != null)
        {
            var fullName = symbol.ContainingType != null 
                ? $"{symbol.ContainingType.FullName}.{symbol.Name}" 
                : symbol.Name;
            Console.WriteLine($"引用的类/方法:{fullName}");
        }
    }
    
  • 快速轻量方案
    如果只是临时手动查看,也可以用VS的「查找所有引用」功能,或者Resharper这类工具的代码分析功能,但如果需要自动化批量处理,Roslyn是首选。

问题2:编译前扫描代码并限制调用范围

这个需求属于插件安全管控的范畴,建议结合Roslyn白名单检查+运行时权限隔离的双重方案,既能在编译前拦截危险代码,又能在运行时做兜底防护。

  • 编译前的Roslyn白名单扫描
    先定义好允许调用的类型/方法白名单(比如你的API、Math类),然后通过Roslyn的语义分析遍历源码中的所有符号引用,检查是否在白名单内:

    // 示例:检查代码是否引用了禁止的类型/方法
    var allowedFullNames = new HashSet<string> 
    { 
        "System.Math", 
        "YourPluginApiNamespace.CoreApi",
        "YourPluginApiNamespace.Utils"
    };
    var forbiddenFullNames = new HashSet<string> 
    { 
        "System.IO.File", 
        "System.IO.StreamWriter",
        "System.Net.WebClient"
    };
    
    foreach (var node in identifierNodes)
    {
        var symbol = semanticModel.GetSymbolInfo(node).Symbol;
        if (symbol?.ContainingType != null)
        {
            var typeFullName = symbol.ContainingType.FullName;
            if (forbiddenFullNames.Contains(typeFullName))
            {
                throw new InvalidOperationException($"代码中引用了禁止的类型:{typeFullName}");
            }
            if (!allowedFullNames.Contains(typeFullName) && !typeFullName.StartsWith("System."))
            {
                // 这里可以根据需求调整:比如允许部分基础System类,或者严格只放行白名单
                throw new InvalidOperationException($"代码中引用了未授权的类型:{typeFullName}");
            }
        }
    }
    

    语义分析能准确识别类型的真实全名,避免开发者通过using别名或者命名空间嵌套绕过检查。

  • 运行时的权限隔离
    即使做了编译前扫描,也建议在加载插件时用AppDomain或者AssemblyLoadContext设置严格的权限,作为兜底:

    // 示例:创建受限的AppDomain,禁止文件IO等危险操作
    var permissionSet = new PermissionSet(PermissionState.None);
    // 只允许执行权限
    permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
    // 允许有限的反射权限(按需调整)
    permissionSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
    
    var domainSetup = new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory };
    var pluginDomain = AppDomain.CreateDomain("RestrictedPluginDomain", null, domainSetup, permissionSet);
    // 从该AppDomain加载插件程序集
    var pluginAssembly = pluginDomain.Load("PluginAssemblyName");
    
  • 进阶方案:自定义Roslyn分析器
    如果需要更复杂的规则(比如禁止特定方法、检查参数合法性),可以创建自定义的Roslyn分析器,将检查逻辑集成到编译流程中,编译时直接抛出错误提示,比手动遍历更高效,也更易于维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:27:37