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

如何从System.CodeDom.Compiler迁移至Roslyn API?代码适配求助

将旧CSharpCodeProvider代码迁移到Roslyn API

核心配置映射

原代码中CompilerParameters和CSharpCodeProvider的配置可直接对应到Roslyn的API,具体映射关系如下:

  • /t:library编译选项 → OutputKind.DynamicallyLinkedLibrary
  • C# 4.0版本指定 → LanguageVersion.CSharp4
  • 引用程序集集合 → MetadataReference列表
  • 内存生成程序集 → 通过MemoryStream加载编译字节码实现

完整迁移代码

替换原有的编译逻辑为以下Roslyn实现:

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

// 保留原有源代码拼接逻辑
sourceCode = $@"  
using System;
{string.Format(Constants.Assembly.UsingDirective, Constants.Assembly.DapperNamespace)}

namespace {Constants.Assembly.DynamicTypeNamespace} {{  
    {sourceCode}
}}";

// 1. 将源代码解析为Roslyn语法树
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);

// 2. 创建编译选项,对应原CompilerParameters的配置
CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(
    outputKind: OutputKind.DynamicallyLinkedLibrary, // 等价于/t:library
    languageVersion: LanguageVersion.CSharp4 // 指定C#4编译版本
);

// 3. 构建引用程序集列表,对应原ReferencedAssemblies
List<MetadataReference> references = new List<MetadataReference>();
foreach (string assemblyPath in baseAssemblyLocations)
{
    references.Add(MetadataReference.CreateFromFile(assemblyPath));
}
// 补充必要的系统依赖(若baseAssemblyLocations未包含)
references.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
references.Add(MetadataReference.CreateFromFile(typeof(Dapper.SqlMapper).Assembly.Location)); // 依赖Dapper时添加

// 4. 创建编译实例
CSharpCompilation compilation = CSharpCompilation.Create(
    assemblyName: Path.GetRandomFileName(), // 生成随机程序集名称
    syntaxTrees: new[] { syntaxTree },
    references: references,
    options: compilationOptions
);

// 5. 执行编译并加载内存程序集
using (MemoryStream ms = new MemoryStream())
{
    EmitResult emitResult = compilation.Emit(ms);
    
    if (!emitResult.Success)
    {
        // 获取第一个编译错误并抛出
        Diagnostic firstError = emitResult.Diagnostics.First(d => d.Severity == DiagnosticSeverity.Error);
        throw new Exception(firstError.GetMessage());
    }
    
    // 重置流位置并加载程序集到内存
    ms.Position = 0;
    Assembly = Assembly.Load(ms.ToArray());
}

关键说明

  • Roslyn通过SyntaxTree抽象源代码,替代原直接传入字符串的方式
  • CSharpCompilation是核心编译对象,整合了语法树、引用和编译选项三大要素
  • 内存生成程序集通过MemoryStream中转,完全等价于原GenerateInMemory = true的行为
  • 编译错误需从EmitResult.Diagnostics中筛选错误级别的诊断信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 03:54:11