I have a string string input;
with some code (all below is in that string)
var x = s.IndexOf("a");
return String.Format(s, x);
Now, I would like to achieve following scenario:
Func<string, string> f = Compile(input);
var test = "dcba - {0}";
var result = f(test);
// result = "dcba - 3";
I assume, that the actual T1, TResult are known (here: string, string), and that input is named "s". I can achieve it this way:
var input = "var x = s.IndexOf(\"a\"); return String.Format(s, x);";
var containerClass = @"using System; class TempClass {{ public string temp_func(string s){{ {0} }} }}";
var code = String.Format(containerClass, input);
// Create a new instance of the C# compiler
var compiler = new CSharpCodeProvider();
var params = new CompilerParameters
{
GenerateExecutable = false,
GenerateInMemory = true
};
params.ReferencedAssemblies.Add("System.dll");
var results = compiler.CompileAssemblyFromSource(params, code);
Func<string, string> f;
if (results.Errors.Count == 0)
{
f = s =>
{
var myClass = results.CompiledAssembly.CreateInstance("TempClass");
return (string) myClass.GetType().
GetMethod("temp_func").
Invoke(myClass, new object[] {s});
};
// test:
Console.WriteLine(f(Console.ReadLine()));
}
But it is fairly complicated way. Is there any way to simplify this, if I know that I just want a Func<T1, TResult>
, not a whole compiled assembly, instancing classes (or calling a static method on one)?
I can take this code, of course, and dress it nicely - wrap it in a generic class, get T1, TResult type names to put into the TempClass
template (String.Format("public {0} temp_func({1} s)",typeof(TResult).Name, typeof(T1).Name);
), but it has a feel of greasing an axle of a square wheel to make ride smoother...
I went with something like this:
The use is fairly simple then: