in order to convert string to code I was using the CodeDom compiler.
I am talking about Compiling C# Code at Runtime!
Especially I want to make Runtime Compilation with several parameters which types can be different.
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Dynamic;
using System.Net;
using System.Reflection;
using Microsoft.CSharp;
static void Main()
{
String2LineOfCommand("P[0].ToString() + P[1].ToString()", new [] { 2, 4});
}
private void String2LineOfCommand(string expresion1, params object[] P)
{
MethodInfo function = CreateFunction(expresion1);
object result = function.Invoke(null, P);
Console.WriteLine(result.ToString());
}
public static MethodInfo CreateFunction(string function)
{
string code1 = @"
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Dynamic;
namespace UserFunctions
{
public class ParametricFunctions
{
public static object Function1(params int[] P)
{
return " + function + @";
}
}
}
";
var providerOptions = new Dictionary<string, string>();
providerOptions.Add("CompilerVersion", "v4.0");
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
CompilerParameters cp = new CompilerParameters();
cp.GenerateInMemory = true;
cp.TreatWarningsAsErrors = false;
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Core.dll");
cp.ReferencedAssemblies.Add("System.Windows.dll");
cp.ReferencedAssemblies.Add("System.Dynamic.dll");
CompilerResults results = provider.CompileAssemblyFromSource(cp, code1);
Type parametricFunction1 = results.CompiledAssembly.GetType("UserFunctions.ParametricFunctions");
return parametricFunction1.GetMethod("Function1");
}
This code works just fine!
But as I told you before I am not talking about int type parameters.
I am talking about different types of input parameters in different situations at runtime!
If I will type
String2LineOfCommand("P[0].ToString() + P[1].ToString()", 2, 4);
Instead of
String2LineOfCommand("P[0].ToString() + P[1].ToString()", new [] { 2, 4});
Then I will get an error message:
An unhandled exception of type 'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll
Additional information: Parameter count mismatch.
Please tell me why?
Also look inside...
public static MethodInfo CreateFunction(string function)
When I am trying to type
public static object Function1(params object[] P)
instead of
public static object Function1(params int[] P)
It shows me an error message:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Object of type 'System.Int32[]' cannot be converted to type 'System.Object[]'.
But when I am trying to type
public static object Function(params dynamic[] P)
compilation fails and there is no message about error!
I think I am missing a reference!
dynamic keyword is available for .net 4.0
I already wrote:
providerOptions.Add("CompilerVersion", "v4.0");
But no result!
PLEASE help me!
The CompilerResults class has an Errors property. The errors for which the compilation fails are there.
Code so that it works with dynamic (or object, I don't see the point of dynamic here):
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using Microsoft.CSharp;
public class Program
{
static void Main()
{
String2LineOfCommand("P[0].ToString() + P[1].ToString()", 2, 4);
}
private static void String2LineOfCommand(string expresion1, params dynamic[] P)
{
MethodInfo function = CreateFunction(expresion1);
object result = function.Invoke(null, new[] { P });
Console.WriteLine(result.ToString());
Debug.WriteLine(result.ToString());
}
public static MethodInfo CreateFunction(string function)
{
string code1 = @"
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Dynamic;
namespace UserFunctions
{
public class ParametricFunctions
{
public static object Function1(dynamic[] P)
{
return " + function + @";
}
}
}
";
var providerOptions = new Dictionary<string, string>();
providerOptions.Add("CompilerVersion", "v4.0");
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
CompilerParameters cp = new CompilerParameters();
cp.GenerateInMemory = true;
cp.TreatWarningsAsErrors = false;
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Core.dll");
cp.ReferencedAssemblies.Add("System.Windows.dll");
cp.ReferencedAssemblies.Add("System.Dynamic.dll");
cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
CompilerResults results = provider.CompileAssemblyFromSource(cp, code1);
Type parametricFunction1 = results.CompiledAssembly.GetType("UserFunctions.ParametricFunctions");
return parametricFunction1.GetMethod("Function1");
}
}