不幸的是,当代码原语组合在一起时,并不总是产生期望的结果,因为提供程序将具有一定的自由度来解释意图。解决这个问题的方法是使用
CodeSnippetExpression
.
下面是代码(vb.net&c),用于生成问题中列出的eval语句。请随意使用最适合您的工具:
VB.NET版本
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.Text
Imports System.IO
Imports Microsoft.CSharp
Public Class PrintEvalStatement
Public provider As CodeDomProvider
Sub New()
Dim left As New CodePrimitiveExpression("throw new Error(""Unhandled Error in Silverlight Application ")
Dim middle As New CodeVariableReferenceExpression("errorMsg")
Dim right As New CodePrimitiveExpression(""");")
Dim targetObject = New CodeTypeReferenceExpression("System.Windows.Browser.HtmlPage.Window")
Dim methodName = "Eval"
provider = New VBCodeProvider()
Dim vbStatement As String = ConcatStatement(left, middle, right, targetObject, methodName)
provider = New CSharpCodeProvider()
Dim csStatement As String = ConcatStatement(left, middle, right, targetObject, methodName)
Console.WriteLine(vbStatement)
Console.WriteLine(csStatement)
Console.ReadLine()
End Sub
Private Function ConcatStatement(ByVal left As CodePrimitiveExpression,
ByVal middle As CodeVariableReferenceExpression,
ByVal right As CodePrimitiveExpression,
ByVal targetObject As CodeTypeReferenceExpression,
ByVal methodName As String) As String
Dim evalMessage As New CodeExpression
evalMessage = ConcatString(left, middle, right)
Dim eval As New CodeMethodInvokeExpression(targetObject, methodName, evalMessage)
Dim evalStatement As New CodeExpressionStatement(eval)
Dim sw As StringWriter = New StringWriter()
Using tx As TextWriter = New StringWriter()
provider.GenerateCodeFromStatement(evalStatement, tx, New CodeGeneratorOptions())
Return tx.ToString()
End Using
End Function
Private Function ConcatString(ByVal left As CodeExpression,
ByVal middle As CodeExpression,
ByVal right As CodeExpression) As CodeExpression
Return New CodeSnippetExpression(CodeToString(left) + " + " + CodeToString(middle) + " + " + CodeToString(right))
End Function
Private Function CodeToString(ByVal expr As CodeExpression) As String
Using tx As TextWriter = New StringWriter()
provider.GenerateCodeFromExpression(expr, tx, New CodeGeneratorOptions())
Return tx.ToString()
End Using
End Function
End Class
C版本
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;
using System.IO;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
namespace CodeDom
{
class Program
{
static CodeDomProvider provider;
static void Main(string[] args)
{
Program shell = new Program();
provider = new VBCodeProvider();
CodePrimitiveExpression left = new CodePrimitiveExpression("throw new Error(\"Unhandled Error in Silverlight Application\")");
CodeVariableReferenceExpression middle = new CodeVariableReferenceExpression("errorMsg");
CodePrimitiveExpression right = new CodePrimitiveExpression("\");");
CodeTypeReferenceExpression targetObject = new CodeTypeReferenceExpression("System.Windows.Browser.HtmlPage.Window");
string methodName = "Eval";
string vbStatement = shell.ConcatStatement(left, middle, right, targetObject, methodName);
provider = new CSharpCodeProvider();
string csStatement = shell.ConcatStatement(left, middle, right, targetObject, methodName);
Console.WriteLine(vbStatement);
Console.WriteLine(csStatement);
Console.ReadLine();
}
public string ConcatStatement(CodePrimitiveExpression left, CodeVariableReferenceExpression middle, CodePrimitiveExpression right, CodeTypeReferenceExpression targetObject, string methodName)
{
CodeExpression evalMessage = new CodeExpression();
evalMessage = ConcatString(left, middle, right);
CodeMethodInvokeExpression eval = new CodeMethodInvokeExpression(targetObject, methodName, evalMessage);
CodeExpressionStatement evalStatement = new CodeExpressionStatement(eval);
using (TextWriter tx = new StringWriter())
{
provider.GenerateCodeFromStatement(evalStatement, tx, new CodeGeneratorOptions());
return tx.ToString();
}
}
private CodeExpression ConcatString(CodeExpression left, CodeExpression middle, CodeExpression right) {
return new CodeSnippetExpression(CodeToString(left) + " + " + CodeToString(middle) + " + " + CodeToString(right));
}
private string CodeToString(CodeExpression expr) {
using (TextWriter tx = new StringWriter()) {
provider.GenerateCodeFromExpression(expr,tx, new CodeGeneratorOptions());
return tx.ToString();
}
}
}
}