Обходной путь для C # CodeDom, вызывающий переполнение стека (CS1647) в csc.exe?

У меня есть ситуация, когда мне нужно сгенерировать класс с большой строкой const. Код вне моего контроля приводит к тому, что мое сгенерированное дерево CodeDom отправляется в исходный код C #, а затем компилируется как часть большей сборки.

К сожалению, я столкнулся с ситуацией, когда, если длина этой строки превышает 335440 символов в Win2K8 x64 (926240 в Win2K3 x86), компилятор C # завершается с фатальной ошибкой:

фатальная ошибка CS1647: выражение слишком длинное или сложное для компиляции рядом с 'int'

MSDN говорит, что CS1647 - это «переполнение стека в компиляторе» (не каламбур!). Присмотревшись повнимательнее, я определил, что CodeDom «красиво» оборачивает мою строку const в 80 символов. Это заставляет компилятор объединять более 4193 фрагментов строки, что, по-видимому, является глубиной стека компилятора C # в x64 NetFx. CSC.exe должен внутренне рекурсивно вычислить это выражение, чтобы «перегидрировать» мою единственную строку.

Мой начальный вопрос таков:Кто-нибудь знает обходной путь, чтобы изменить, как генератор кода генерирует строки?«Я не могу контролировать тот факт, что внешняя система использует источник C # в качестве промежуточного звена, и я хочу, чтобы это было константой (а не конкатенацией строк во время выполнения).

С другой стороны,как я могу сформулировать это выражение так, чтобы после определенного числа символов я все еще мог создать константу, но она состоит из несколькихбольшой глыбы?

Полное воспроизведение здесь:

// 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 = "XXXX...";

CodeMemberField field = new CodeMemberField();
field.Name = "HugeString";
field.Type = new CodeTypeReference(typeof(String));
field.Attributes = MemberAttributes.Public|MemberAttributes.Const;
field.InitExpression = new CodePrimitiveExpression(HugeString);
type.Members.Add(field);

// generate class file
using (TextWriter writer = File.CreateText("FooBar.cs"))
{
    provider.GenerateCodeFromCompileUnit(code, writer, new CodeGeneratorOptions());
}

// compile class file
CompilerResults results = provider.CompileAssemblyFromFile(new CompilerParameters(), "FooBar.cs");

// output reults
foreach (string msg in results.Output)
{
    Console.WriteLine(msg);
}

// output errors
foreach (CompilerError error in results.Errors)
{
    Console.WriteLine(error);
}

Ответы на вопрос(5)

Ваш ответ на вопрос