Jest to z pewnością możliwe. Klasa CodeSnippetCompileUnit w zasadzie to robi. Napisałem ci przykładowy kod użycia. Będziesz musiał uwzględnić te przestrzenie nazw:
- System.CodeDom.Compiler;
- System.CodeDom;
- Microsoft.CSharp;
- System.Reflection;
Oto kod:
string source = @"
class MyType
{
public static int Evaluate(<!parameters!>)
{
return <!expression!>;
}
}
";
string parameters = "int a, int b, int c";
string expression = "a + b * c";
string finalSource = source.Replace("<!parameters!>", parameters).Replace("<!expression!>", expression);
CodeSnippetCompileUnit compileUnit = new CodeSnippetCompileUnit(finalSource);
CodeDomProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
CompilerResults results = provider.CompileAssemblyFromDom(parameters, compileUnit);
Type type = results.CompiledAssembly.GetType("MyType");
MethodInfo method = type.GetMethod("Evaluate");
// The first parameter is the instance to invoke the method on. Because our Evaluate method is static, we pass null.
int result = (int)method.Invoke(null, new object[] { 4, -3, 2 });
zastąpić „parametry” oraz „wyrażenia” przez cokolwiek, i masz sobie ogólną wyrażeń.
Jeśli pojawi się wyjątek FileNotFoundException w results.CompiledAssembly, to nie można skompilować fragmentu kodu.
Możesz również rzucić okiem na klasę System.CodeDom.CodeSnippetExpression. Służy do bardziej szczegółowego czytania wyrażeń, ale samo wyrażenie nie może być skompilowane, więc będziesz potrzebował więcej CodeDom do zbudowania klasy i metody pracy wokół niej. Jest to przydatne, jeśli chcesz programowo manipulować rodzajem klasy, którą generujesz. CodeSnippetCompileUnit jest fajny do generowania całej klasy pracującej jednocześnie (i prostszego przykładu), ale aby nią manipulować, musiałbyś wykonywać niewygodne manipulacje ciągami.
zadałem podobne pytanie jakiś czas temu. Możesz przyjrzeć się niektórym z tych odpowiedzi: http://stackoverflow.com/questions/234217/is-it-possible-to-translate-a-user-entered-mathematical-equation-into-ccode-at – raven
Czy znalazłeś sposób na połączenie ze zmiennymi użytymi w pozostałej części "statycznego/wstępnie skompilowanego" kodu? –