English 中文(简体)
C# CodeDom Console.WriteLine + MethodReference
原标题:

I am attempting to create a Console.WriteLine statement (shown below) using CodeDom. This is giving me mainly because of the Environment.NewLine call - I can t figure out the proper way of embedding a method within the Console.WriteLine call. I will show you the code I am trying to produce along with the code that I am using. Perhaps someone will be able to catch, and correct my error.

The code I would like to produce:

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

The code that I am using:

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")})));

The code that is being generated:

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

Because I am using MethodInvoke, CodeDom is separating each line by a ", " as if they were each new parameters within the same method... How can I go about this the proper way?

最佳回答

You have to write the CodeDOM the same way you write the code normally. That is, when you want to call a method with one argument, you have to give it one argument.

Also, if you want to have a constant in the generated code, the proper way is to use CodePrimitiveExpression. You are trying to creating a variable with the name "Error reading from source: ".

Because constructing the whole expression by hand would be tedious and unreadable, you could create a helper method for joining multiple expressions using the same operator:

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

Using that, you can now write:

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")));

Which produces the following code:

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

Of course, you can always use snippets:

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

Also, using the formatting overload of Console.WriteLine() might be better.

问题回答

Use the Console.WriteLine(String, Object[]) overload and do the equivalent to

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

in CodeDom.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签