Есть ли простой способ создать метод и установить его тело динамически в C #? - PullRequest
4 голосов
/ 07 июня 2010

Я держу тело метода в строке.Я хочу создать метод динамически.Но я не знаю, как настроить его тело.Я видел очень нудный способ использования CodeDom.И я видел использование Emit с OpCodes.Есть ли способ использовать готовый код из строковой переменной?

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

Ответы [ 3 ]

7 голосов
/ 07 июня 2010

Звучит так, как будто вам нужен «компилятор как сервис».Это не в MS .NET 4.0, но может быть в более позднем выпуске.Это уже в Моно, хотя.До этого момента доступны следующие параметры:

  • use CSharpCodeProvider, но вам придется загрузить его как метод (и создать для него делегата) с помощью отражения
  • используйте CodeDom
  • используйте Reflection.Emit
  • используйте Expression

В 4.0 API Expression гораздо богаче, чем в 3.5,позволяя большинству обычных конструкций без боли CodeDom.Но не стоит сбрасывать со счетов Reflection.Emit - требуется некоторое время, чтобы разобраться с ILGenerator и использовать стек, но это не так плохо, как думают люди.

Как побочный эффектобратите внимание, не используйте Invoke из DynamicMethod, если только вы не хотите выполнить его один раз.Лучше использовать CreateDelegate, а затем сохранить (и повторно использовать) этот делегат:

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();

Или с Expression API:

var lambda =Expression.Lambda<Func<string>>(Expression.Constant("Hello, world"));
var func = lambda.Compile();
var s = func();
1 голос
/ 07 июня 2010

Вам нужно взглянуть на следующие пространства имен:

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

Это может помочь вам начать: http://www.west -wind.com / Presentations / dynamicCode / DynamicCode.htm

1 голос
/ 07 июня 2010

Сохраните это в файл .CS, скомпилируйте и выполните на лету.

...