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.
精彩评论