【问题标题】:C# CodeDom Console.WriteLine + MethodReferenceC# CodeDom Console.WriteLine + MethodReference
【发布时间】:2011-07-19 17:55:46
【问题描述】:

我正在尝试使用 CodeDom 创建一个Console.WriteLine 语句(如下所示)。这给了我主要是因为 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 用“,”分隔每一行,就好像它们是同一个方法中的每个新参数......我该如何解决这个问题 proper 方式?

【问题讨论】:

  • 你可以使用程序员的方法来解决问题——忽略它们。你可以试试"Error reading source: {0} Error code: {1}"...
  • 这也更干净:)

标签: c# methods codedom console.writeline


【解决方案1】:

您必须以与正常编写代码相同的方式编写 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))

当然,你总是可以使用 sn-ps:

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

另外,使用Console.WriteLine() 的格式重载可能会更好。

【讨论】:

    【解决方案2】:

    使用Console.WriteLine(String, Object[]) 重载并执行等效于

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

    在 CodeDom 中。

    【讨论】:

    • 好吧 - 我很快就能测试出来。一旦我得到它的工作,我会报告回来。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2010-10-09
    • 2016-08-02
    • 2023-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多