标签: codedom

解决C#CodeDom在csc.exe中导致堆栈溢出(CS1647)的问题?

我有一种情况需要生成一个带有大字符串const的类.我控制之外的代码导致我生成的CodeDom树被发送到C#源,然后被编译为更大的Assembly的一部分.

不幸的是,我遇到这种情况,如果这个字符串的长度超过Win2K8 x64中的335440个字符(Win2K3 x86中的926240),则C#编译器会以致命错误退出:

致命错误CS1647:在'int'附近编译表达式太长或太复杂

MSDN称CS1647是"编译器中的堆栈溢出"(没有双关语!).仔细观察我已经确定CodeDom"很好地"将我的字符串const包装在80个字符处.这导致编译器连接4193个字符串块,这显然是x64 NetFx中C#编译器的堆栈深度.CSC.exe必须在内部递归计算此表达式以"重新水化"我的单个字符串.

我最初的问题是:"有没有人知道改变代码生成器如何发出字符串的解决办法? "我无法控制外部系统使用C#source作为中间件的事实,我希望这是一个常量(而不是而不是字符串的运行时串联).

或者,我该怎么制定这个表达式使得一定数量的字符后,我仍然能够创造一个恒定的,但它是由多个的大型块?

完整的repro在这里:

// this string breaks CSC: 335440 is Win2K8 x64 max, 926240 is Win2K3 x86 max
string HugeString = new String('X', 926300);

CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
CodeCompileUnit code = new CodeCompileUnit();

// namespace Foo {}
CodeNamespace ns = new CodeNamespace("Foo");
code.Namespaces.Add(ns);

// public class Bar {}
CodeTypeDeclaration type = new CodeTypeDeclaration();
type.IsClass = true;
type.Name = "Bar";
type.Attributes = MemberAttributes.Public;
ns.Types.Add(type);

// public const string HugeString …
Run Code Online (Sandbox Code Playgroud)

c# compiler-construction codedom csc

7
推荐指数
1
解决办法
7050
查看次数

如何使用CodeDOM创建泛型类,其泛型参数是我创建的类型?

我有一个使用CodeDOM创建的类:

CodeTypeDeclaration some_class = new CodeTypeDeclaration("SomeClass");
// ... properties and methods creation elided
Run Code Online (Sandbox Code Playgroud)

我想创建一个"SomeClass"类型的List.但是,我似乎无法这样做:

var list_type = new CodeTypeReference(typeof (List<>).Name, ??? some_class ???);
var member_field = new CodeMemberField(list_type, field_name)
                                      {
                                               Attributes = MemberAttributes.Private,
                                      }; 
Run Code Online (Sandbox Code Playgroud)

CodeTypeReference不接受a CodeTypeDeclaration,这是我需要的.我能做什么?我并不想通过类的字符串名字,因为这可能会导致错误.

c# codedom

7
推荐指数
1
解决办法
3053
查看次数

我们可以同时从CodeExpressions和文字源代码构造一个程序集吗?

我有一种情况,我的代码的一部分是CodeExpressions由用户自己生成的,另一部分是由用户自己生成的(例如:用户只需像往常一样编写代码,然后我会在编译时将其添加到我的程序集中).

是否可以生成包含这两个项目的程序集?警告:这两种方法将包含partial类,因此它们必须位于同一个程序集中.

我想到的另一种方法是将这两种方法转换为字符串表示,然后从该字符串生成程序集,但我怀疑我可以从用户生成的类型中获取源代码(在编译时).

根据这个想法,我可以将CodeExpressions生成的代码写入文本文件并将其与.cs文件结合起来.时间表看起来像这样:

  • 用户写了他的课
  • CodeDom树以编程方式设置
  • 用户构建项目
  • CodeDom生成文本文件的源
  • 程序读取用户定义.cs文件的内容
  • 程序读取生成的文本文件
  • 程序结合了这两个
  • 程序.dll从组合源代码中创建一个新的

我可以跳过将我生成的CodeDom源写入和读取文本文件的(冗余)步骤,并简单地将其写入内存,当然.事实上,使用预处理T4模板并将这些模板的结果加载到内存中并从该字符串编译程序集可能最简单.

正如你所看到的,这是非常混乱的,但现在它看起来是最可行的.我是否看过任何可能使这更容易的选项?

背景:

我正在创建一个库,该库将创建一个包含用户定义的类的程序集.这种方式的工作方式如下:

  • 用户在他的项目中引用我的库
  • 用户创建新TinyTypeSetup实例
  • 用户为其添加了Tiny Type定义
  • 用户运行程序
  • 程序通过CodeDom从给定类型生成程序集

我现在想要添加的是用户可以创建自己的源文件并立即将这些文件添加到生成的程序集中.这将允许用户使用他自己的方法指定部分类,除了我自己生成的那些.

c# code-generation codedom .net-assembly

7
推荐指数
1
解决办法
279
查看次数

在.netstandard 2.0上迁移后无法编译简单的动态代码(CodeDom抛出System.PlatformNotSupportedException)

尝试编译此代码示例:

var c = new CSharpCodeProvider();
var cp = new CompilerParameters();
var className = $"CodeEvaler_{Guid.NewGuid().ToString("N")}";
// doesn't work with or without netstandard reference
var netstandard = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
cp.ReferencedAssemblies.Add(netstandard.Location);
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;

var sb = new StringBuilder("");

sb.Append("namespace Jobs.Dynamic{ \n");
sb.Append($"public class {className} {{\n");
sb.Append($"public object RunSnippetCode()\n{{\n");
sb.Append("\nreturn null;\n");
sb.Append("\n}\n");
sb.Append("}");
sb.Append("}");

CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
Run Code Online (Sandbox Code Playgroud)

在.netstandard 2.0上进行迁移之前,一切正常

必须生成一个简单的类,并且只要复制代码并在Visual Studio中运行它,它就可以工作。具有一个返回null的方法的类。现在,CompileAssemblyFromSource方法将引发

System.PlatformNotSupportedException:该平台不支持该操作。在Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options,String [] fileNames)在Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters选项,String []源)在CnetContent.Jobs.Dyn。 ctor(IEnumerable 1 referencedAssemblies, IEnumerable1 usings,String methodArgs,String codeSnippet)在CnetContent.Jobs.Core.JobBase.EvalRunCondition(String&错误)

我更新了System.CodeDom,并且此库支持.netstandard …

c# codedom system-codedom-compiler .net-standard-2.0

7
推荐指数
1
解决办法
2206
查看次数

ASP.NET CodeDom 提供程序无法定位错误

在服务器上部署时遇到 ASP.NET 错误:

无法找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”。

此错误仅发生在特定服务器上,在本地或另一台服务器上执行时,它工作得很好。

packages.config CodeDom 行

  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.0" targetFramework="net461" />
Run Code Online (Sandbox Code Playgroud)

Web.Config CodeDom 行

  <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
Run Code Online (Sandbox Code Playgroud)

c# asp.net codedom

7
推荐指数
1
解决办法
1万
查看次数

CodeDom - 调用泛型方法

有没有人知道用CodeDom调用基类的泛型方法的方法?

调用标准方法没问题,但我找不到调用泛型的解决方案.

我用来调用标准基类方法GetInstance的代码:

CodeAssignStatement assignStatement = new CodeAssignStatement(
     new CodeVariableReferenceExpression("instance"),
     new CodeMethodInvokeExpression(
         new CodeThisReferenceExpression(),
         "GetInstance",
         new CodeExpression[] { new CodeVariableReferenceExpression("instance") }
     ));
Run Code Online (Sandbox Code Playgroud)

generics codedom

6
推荐指数
1
解决办法
3958
查看次数

以编程方式格式化生成的CodeDom代码

如何确保从以下代码生成的CS格式良好,即好像我们按下CTRL+ K+ D?这是C#

我们正在做的事情:

CodeMemberMethod membMethod = new CodeMemberMethod();
membMethod.Attributes = MemberAttributes.Static | MemberAttributes.Public;
membMethod.ReturnType = new CodeTypeReference("IEnumerable<" + TableNameAsSinglular + ">");
membMethod.Name = "Get" + TableName;
membMethod.Statements.Add(new CodeSnippetStatement(DataBaseContext + " dcontext = new " + DataBaseContext + "(ConnectionString);"));
membMethod.Statements.Add(new CodeSnippetStatement("var records = from record in dcontext." + TableName + " select new " + TableNameAsSinglular + "{"));
    int iCount = 0;

    //Add columns fields
    foreach (DataRow dr in sqlTable.Rows)
    {
        if (iCount == 4)
        break; …
Run Code Online (Sandbox Code Playgroud)

c# code-generation codedom

6
推荐指数
1
解决办法
3937
查看次数

如何使用 CodeDOM 在 AppDomain 中创建和加载程序集?

我正在开发一个项目,该项目将使用 CodeDOM 创建一个类,该类评估用户定义的表达式、为该类创建程序集并加载该程序集。由于可以有相当数量的用户定义表达式,我想首先创建一个 AppDomain,为该 AppDomain 中的程序集执行 CodeDOM 创建/加载和执行,然后卸载 AppDomain。

我搜索了不少,并且发现了如何加载现有装配成一个AppDomain的例子很多,但我似乎无法找到一个节目我如何从创建装配的应用程序域。

此示例 ( DynamicCode ) 使用 CodeDOM 创建一个程序集,然后将其加载到 AppDomain 中,但是,作者将程序集生成到磁盘。我更愿意在内存中生成程序集,这样我就不必管理生成的程序集的清理工作。(即使这确实在临时文件夹中创建了一个 .dll)。

谁能指出我如何做到这一点的例子?

任何帮助将不胜感激。

我已经从我的代码中摘录了一些摘录,这样你们都可以了解我到目前为止的内容:

private string CreateSource()
{
    CodeCompileUnit codeUnit = new CodeCompileUnit();
    CodeNamespace codeNamespace = new CodeNamespace(Namespace);
    CodeTypeDeclaration codeClass = new CodeTypeDeclaration
    {
        Name = "ExpressionEvaluator",
        IsClass = true,
        TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed
    };

    codeNamespace.Types.Add(codeClass);
    codeUnit.Namespaces.Add(codeNamespace);

    AddMethods(codeClass);

    string result = GenerateSourceCode(codeUnit);

    return result.ToString();
}

private CompilerResults CompileSource(string source)
{
    using (CodeDomProvider provider = new CSharpCodeProvider())
    {
        CompilerParameters …
Run Code Online (Sandbox Code Playgroud)

.net codedom appdomain

6
推荐指数
1
解决办法
5028
查看次数

使用System.CodeDom生成扩展方法

有没有人试过在.NET 4.0下使用System.CodeDom生成扩展方法?似乎没有任何方法可以将CodeMemberMethod或CodeParameterDeclarationExpression指定为扩展方法/参数.

如果无法做到这一点,有什么好的解决方法吗?

谢谢

c# extension-methods codedom system-codedom-compiler

6
推荐指数
1
解决办法
939
查看次数

如何从源代码构建CodeCompileUnit?

如何从源代码构建CodeCompileUnit?

解析C#源代码的最佳方法是什么?

CodeCompileUnit是正确的选择吗?和怎么样?

谢谢

c# codedom

6
推荐指数
2
解决办法
4783
查看次数