C # CodeDom Console.WriteLine + MethodReference - PullRequest
0 голосов
/ 19 июля 2011

Я пытаюсь создать оператор Console.WriteLine (показанный ниже), используя CodeDom.Это дает мне в основном из-за вызова Environment.NewLine - я не могу понять правильный способ встраивания метода в вызов Console.WriteLine.Я покажу вам код, который я пытаюсь создать вместе с кодом, который я использую.Возможно, кто-то сможет поймать и исправить мою ошибку.

Код, который я хотел бы , чтобы произвести:

Console.WriteLine("Error reading from source: " + Environment.NewLine + "Error code: " + ex.Message);

Код, который я использую:

const char quote = '\u0022'; // Represents a " mark
CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("Console"), "WriteLine",
new CodeExpression[] {
new CodeVariableReferenceExpression(quote + "Error reading from source: " + quote + " + "),
new CodeFieldReferenceExpression("Environment"), "NewLine"),
new CodeVariableReferenceExpression("+ " + quote + "Error code: " + quote + " + " + "ex" + ".Message")})));

Код, который генерируется:

Console.WriteLine("Error reading source: " + , Environment.NewLine, + "Error code: " + ex.Message);

Поскольку я использую MethodInvoke, CodeDom разделяет каждую строку на «,» как если бы они были каждым новым параметром в одном и том же методе ... Как я могу это сделать правильным способом?

Ответы [ 2 ]

1 голос
/ 20 июля 2011

Вы должны написать CodeDOM так же, как обычно. То есть, когда вы хотите вызвать метод с одним аргументом, вы должны дать ему один аргумент.

Также, если вы хотите иметь константу в сгенерированном коде, правильный способ - использовать CodePrimitiveExpression. Вы пытаетесь создать переменную с именем "Error reading from source: ".

Поскольку создание всего выражения вручную было бы утомительным и нечитаемым, вы можете создать вспомогательный метод для объединения нескольких выражений с использованием одного и того же оператора:

static CodeExpression Join(
    CodeBinaryOperatorType op, params CodeExpression[] expressions)
{
    return expressions.Aggregate((l, r) => new CodeBinaryOperatorExpression(l, op, r));
}

Теперь вы можете написать:

new CodeMethodInvokeExpression(
    new CodeTypeReferenceExpression(typeof(Console)), "WriteLine",
    Join(CodeBinaryOperatorType.Add,
            new CodePrimitiveExpression("Error reading from source: "),
            new CodePropertyReferenceExpression(
                new CodeTypeReferenceExpression(typeof(Environment)),
                "NewLine"),
            new CodePrimitiveExpression("Error code: "),
            new CodePropertyReferenceExpression(
                new CodeVariableReferenceExpression("ex"), "Message")));

Который производит следующий код:

System.Console.WriteLine(((("Error reading from source: " + System.Environment.NewLine)
                + "Error code: ")
                + ex.Message))

Конечно, вы всегда можете использовать фрагменты:

new CodeMethodInvokeExpression(
    new CodeTypeReferenceExpression(typeof(Console)), "WriteLine",
    new CodeSnippetExpression(
        "\"Error reading from source: \" + Environment.NewLine + \"Error code: \" + ex.Message"));

Кроме того, использование перегрузки форматирования Console.WriteLine() может быть лучше.

0 голосов
/ 19 июля 2011

Используйте перегрузку Console.WriteLine (String, Object []) и выполните эквивалент

Console.WriteLine("Error reading from source: {0} Error code: {1}", 
    Environment.NewLine, 
    ex.Message);

в CodeDom.

...