5

I have the body of a method stored as a string and I'm looking to create this method dynamically. However, I'm unsure how to assign its body. I've come across a rather complex method using CodeDom, and another using Emit with OpCodes. Is there a simpler way to utilize the existing code from a string variable?

string method_body = "return \"Hello, world!\";"; // there is a method body DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("My_method", typeof(string), new Type[] { }); // some way to create method dynamically // any way to set body? string result = (string)dm.Invoke(...); // I need to write result in a variable 

3 Answers 3

7

It sounds like what you want is the "compiler as a service". That is not in MS .NET 4.0, but may be in a later release. It is already in Mono, though. Until then, the options available are:

  • use CSharpCodeProvider, but you'll have to load it in as a method (and create a delegate to it) via reflection
  • use CodeDom
  • use Reflection.Emit
  • use Expression

In 4.0, the Expression API is far richer than it was in 3.5, allowing most common constructs without the pain of CodeDom. But don't discount Reflection.Emit - it takes a little while to get your head around ILGenerator and using the stack, but it isn't as bad as people tend to think.

As a side-note, don't use Invoke from DynamicMethod unless you only want to execute it once. The better approach is to use CreateDelegate, then store (and re-use) that delegate:

var dm = new System.Reflection.Emit.DynamicMethod("My_method", typeof(string), null); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldstr, "Hello, world!"); il.Emit(OpCodes.Ret); Func<string> func = (Func<string>)dm.CreateDelegate(typeof(Func<string>)); var s = func(); 

Or with the Expression API:

var lambda =Expression.Lambda<Func<string>>(Expression.Constant("Hello, world")); var func = lambda.Compile(); var s = func(); 
Sign up to request clarification or add additional context in comments.

Comments

2

You need to take a look at these namespaces:

System.Reflection; System.CodeDom.Compiler; Microsoft.CSharp; 

This may get you started: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

2 Comments

Oh, thanks! There is the ready class for dynamic compilation in the article, which you refers to. Suffice it to write wwScripting lo_script = new wwScripting("CSharp"); lo_script.lSaveSourceCode = true; lo_script.AddAssembly("mscorlib.dll"); string result = (string)lo_script.ExecuteCode(method_body, new object[] { .../*params*/...}); It's very convenient way.
That way will work, but you should use that method only if you absolutely trust whatever input code is there. If some end user (or, perhaps some downloadable content) has the ability to run code, you should be very careful. Just an FYI so it doesn't bite you down the road.
1

Save this to a .CS file and compile and execute it on the fly.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.