Malheureusement, les primitives de code, lorsqu'elles sont combinées, ne produisent pas toujours les résultats désirés parce que le fournisseur prendra certaines libertés pour interpréter l'intention. Le chemin autour de ceci est d'utiliser un CodeSnippetExpression.
Voici le code (VB.NET & C#) qui fonctionne pour produire les instructions Eval que vous avez listées dans votre question. Ne hésitez pas à utiliser selon qui fonctionne le mieux pour vous:
VB.NET Version
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# Version
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();
}
}
}
}
Je ne comprends pas votre exemple C#. Votre chaîne littérale contient deux guillemets doubles dans une rangée. Ce n'est pas légal C#. Ironiquement, votre exemple VB.NET, pour le littéral, est C# valide, alors pourquoi ne pas l'utiliser? –
@Kirk Woll: L'exemple n'est pas à moi, c'est Microsoft.C'est ce qui est généré dans App.xaml.vb ou App.xaml.cs pour un nouveau projet Silverlight dans VS. Ce qu'il semble faire, c'est envoyer un message d'erreur à Javascript. –
Mais je ne vois pas comment l'exemple MS pourrait éventuellement compiler. Suggérez-vous que c'est le cas? –