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

如何在当前应用内从字符串/外部文本文件执行C#主代码片段?

嘿,我完全get到你的需求了——你不是要把文本文件里的C#代码当成独立的外部模块或者命名空间来跑,而是希望它能像你亲手写在主程序里的代码片段一样执行,和主程序共享上下文对吧?之前搜的Roslyn相关帖子没找到合适的方案,那我给你两个贴合需求的实现思路,都是基于Roslyn来做的:

场景1:文本代码是主方法内的代码片段(可直接访问主程序变量)

如果你的文本文件里是类似Console.WriteLine("测试");这种主方法内的代码片段,还需要访问主程序里定义的变量,那用Roslyn的脚本API就完美解决,它能让文本代码和主程序共享上下文。

步骤:

  1. 先安装NuGet包:Microsoft.CodeAnalysis.CSharp.Scripting
  2. 编写主程序代码,把变量传递给脚本并执行文本内容:
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System.IO;

class Program
{
    static async Task Main(string[] args)
    {
        // 从文本文件读取代码片段
        string codeSnippet = File.ReadAllText("myCode.txt");

        // 主程序里的变量,让文本代码能直接访问
        int appVersion = 10;
        string appName = "MyDynamicApp";

        // 配置脚本选项:引用必要的程序集,添加常用命名空间
        var scriptOptions = ScriptOptions.Default
            .AddReferences(typeof(Program).Assembly, typeof(Console).Assembly)
            .AddImports("System");

        // 把主程序变量打包成全局对象,供脚本访问
        var globals = new { appVersion, appName };

        // 执行文本里的代码
        await CSharpScript.EvaluateAsync(codeSnippet, scriptOptions, globals);
    }
}

比如你的myCode.txt内容可以是:

Console.WriteLine($"当前应用版本:{appVersion}");
Console.WriteLine($"欢迎使用{appName}!");
int calcResult = appVersion * 2;
Console.WriteLine($"版本翻倍是:{calcResult}");

运行后,这段文本代码就像直接写在Main方法里一样,完全共享主程序的变量和上下文。

场景2:文本代码包含完整类/方法(融合到主程序的命名空间)

如果你的文本文件里是完整的类定义(甚至带using语句),希望它和主程序在同一个命名空间下,而不是独立的外部命名空间,那可以用Roslyn的动态编译API,把主程序模板和文本代码拼接成完整的编译单元,再编译执行。

步骤:

  1. 安装NuGet包:Microsoft.CodeAnalysis.CSharp
  2. 编写代码完成拼接、编译、执行:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.IO;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        // 读取文本文件里的完整代码
        string textClassCode = File.ReadAllText("myClassCode.txt");

        // 构建完整的代码:主程序模板 + 文本代码(同命名空间)
        string fullCompilationCode = $@"
using System;

namespace MyMainApp
{{
    class Program
    {{
        static void Main(string[] args)
        {{
            // 调用文本代码里的方法
            TextEmbeddedCode.RunMyLogic();
        }}
    }}

    // 把文本里的类嵌入到主命名空间下
    {textClassCode}
}}";

        // 配置编译需要的程序集引用
        var references = new[]
        {
            MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
            MetadataReference.CreateFromFile(typeof(Console).Assembly.Location)
        };

        // 解析代码语法树并编译
        var syntaxTree = CSharpSyntaxTree.ParseText(fullCompilationCode);
        var compilation = CSharpCompilation.Create(
            "DynamicMainAssembly",
            new[] { syntaxTree },
            references,
            new CSharpCompilationOptions(OutputKind.ConsoleApplication));

        // 编译到内存流
        using var memoryStream = new MemoryStream();
        var compileResult = compilation.Emit(memoryStream);

        // 处理编译错误
        if (!compileResult.Success)
        {
            var errors = compileResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error);
            foreach (var error in errors)
            {
                Console.WriteLine($"编译错误:{error.GetMessage()}");
            }
            return;
        }

        // 加载编译后的程序集并执行Main方法
        memoryStream.Seek(0, SeekOrigin.Begin);
        var assembly = Assembly.Load(memoryStream.ToArray());
        var programType = assembly.GetType("MyMainApp.Program");
        var mainMethod = programType.GetMethod("Main", BindingFlags.Static | BindingFlags.Public);
        mainMethod.Invoke(null, new object[] { new string[0] });
    }
}

比如你的myClassCode.txt内容可以是:

public static class TextEmbeddedCode
{
    public static void RunMyLogic()
    {
        Console.WriteLine("我是文本文件里的类,和主程序在同一个命名空间!");
        for(int i=0; i<3; i++)
        {
            Console.WriteLine($"循环次数:{i+1}");
        }
    }
}

这样编译执行后,文本里的类就完全是主程序命名空间的一部分,和你自己写的代码没区别。

重要注意事项

  • 安全风险:执行外部来源的文本代码非常危险,一定要确保文件来源绝对可信,避免被注入恶意代码。
  • 性能优化:动态编译有一定开销,如果需要频繁执行同一段文本代码,可以缓存编译后的程序集,避免重复编译。
  • 程序集引用:如果文本代码用到了第三方库,要在编译选项里添加对应的程序集引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:12:53