2010-08-14 19 views
4

J'ai fait des recherches sur ce sujet, mais je n'ai rien trouvé de solide et je voulais voir si quelqu'un pouvait me diriger dans la bonne direction. J'essaie de voir si Codedom peut gérer les chaînes et la concaténation entre les différentes langues, sans que je mette en place des chaînes conditionnelles par langue.Codedom et la manipulation de chaînes

Par exemple, je dois générer les éléments suivants exactement comme indiqué ci-dessous dans C# et VB.NET via CodeDom:

C#

errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n"); 
System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); 

VB.NET

errorMsg = errorMsg.Replace(""""c, "'"c).Replace(ChrW(13) & ChrW(10), "\n") 
System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(""Unhandled Error in Silverlight Application " + errorMsg + """);") 

Le CodeMethodInvokeExpression pour errorMsg.Replace et System.Windows.Browser.HtmlPage.Window.Eval est assez simple, c'est la chaîne à l'intérieur d'eux que je ne peux pas comprendre si Codedom peut gérer automatiquement.

+0

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? –

+0

@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. –

+0

Mais je ne vois pas comment l'exemple MS pourrait éventuellement compiler. Suggérez-vous que c'est le cas? –

Répondre

3

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(); 
      } 
     } 
    } 
} 
+0

+1. Très complet Laisse-moi tester ça. –

+0

J'ai bien travaillé, merci! –

1

Mise à jour: Je viens d'essayer le code suivant:

VBCodeProvider vbProvider = new VBCodeProvider(); 
CSharpCodeProvider csProvider = new CSharpCodeProvider(); 

var errorMessagePart1 = new CodePrimitiveExpression("Unhandled Error in Silverlight Application \""); 
var errorMessagePart2 = new CodeVariableReferenceExpression("errorMsg"); 
var errorMessagePart3 = new CodePrimitiveExpression("\""); 
var errorMessage = new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(errorMessagePart1, CodeBinaryOperatorType.Add, errorMessagePart2), CodeBinaryOperatorType.Add, errorMessagePart3); 
var expression = new CodeThrowExceptionStatement(new CodeObjectCreateExpression("Error", errorMessage)); 

StringWriter writer = new StringWriter(); 
vbProvider.GenerateCodeFromStatement(expression, writer, new CodeGeneratorOptions()); 
string vb = writer.ToString(); 
writer = new StringWriter(); 
csProvider.GenerateCodeFromStatement(expression, writer, new CodeGeneratorOptions()); 
string cs = writer.ToString(); 

Console.WriteLine(vb); 
Console.WriteLine(cs); 

Il imprime:

Throw New [Error]((("Unhandled Error in Silverlight Application """ + errorMsg) _ 
    + """")) 

throw new Error((("Unhandled Error in Silverlight Application \"" + errorMsg) 
    + "\"")); 

Ce qui me semble comme une version VB et une version C#. Vous ne pouvez pas faire grand-chose à propos des fausses parenthèses, mais cela ne devrait pas causer de dommages.

+0

Non, malheureusement cela ne fonctionne pas dans VB <-> C# dans les deux cas –

+0

Mis à jour ma réponse, s'il vous plaît voir si cela fonctionne pour vous. –

+0

+1. Un effort courageux, vraiment intéressant comment vous avez fait cela. Malheureusement, j'ai besoin de l'ensemble comme une ficelle et je n'ai pas été en mesure de travailler à partir de l'ode ci-dessus. –

1

Vous pouvez appeler String.Concat au lieu d'utiliser l'opérateur + sauf si vous devez générer le code exactement comme indiqué.

CodePrimitiveExpression throwstring = new CodePrimitiveExpression("throw new Error(\"Unhandled Error in Silverlight Application "); 
CodeVariableReferenceExpression errorMsg = new CodeVariableReferenceExpression("errorMsg"); 
CodePrimitiveExpression end = new CodePrimitiveExpression("\");"); 

CodeTypeReferenceExpression targetObject = new CodeTypeReferenceExpression("System.Windows.Browser.HtmlPage.Window"); 
CodeTypeReferenceExpression str = new CodeTypeReferenceExpression(typeof(string)); 
CodeMethodInvokeExpression concat = new CodeMethodInvokeExpression(str,"Concat",throwstring,errorMsg,end); 
CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(targetObject, "Eval"), concat); 

Sorties C#:

System.Windows.Browser.HtmlPage.Window.Eval(string.Concat("throw new Error(\"Unhandled Error in Silverlight Application ", errorMsg, "\");")) 

VB:

System.Windows.Browser.HtmlPage.Window.Eval(String.Concat("throw new Error(""Unhandled Error in Silverlight Application ", errorMsg, """);")) 
+0

Désolé, cela n'aide pas beaucoup. Comme indiqué dans la question ci-dessus, j'ai besoin de générer ces chaînes/déclarations. Je vais modifier la question pour ajouter les mots "exactement comme indiqué ci-dessous". –