Создание функции динамично во времени выполнения

Имя:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`{|}~.

Сервер:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.
6
задан denis phillips 3 July 2009 в 16:25
поделиться

7 ответов

Самый простой способ сделать это, вероятно, - это DLINQ, как предлагает TcK.

Самый быстрый (я считаю, в версии 3.5) - создать DynamicMethod . Это также самый страшный метод. По сути, вы создаете метод с использованием IL, который выглядит примерно так же, как написание кода на машинном языке.

Мне нужно было сделать это, чтобы динамически присоединять обработчики событий к тем или иным вещам (ну, мне не нужно было сделай это, я просто хотел упростить события модульного тестирования). В то время это казалось немного пугающим, потому что я не разбираюсь в чуши про IL, но я придумал простой способ добиться этого.

Что вы делаете, так это создаете метод, который делает именно то, что вы хотите. Чем компактнее, тем лучше. Я бы привел пример, если бы мог точно понять, что вы пытаетесь сделать. Вы пишете этот метод в классе внутри проекта DLL и компилируете его в режиме выпуска. Затем вы открываете DLL в Reflector и разбираете свой метод. Reflector дает вам возможность выбрать, на каком языке вы хотите разобрать - выберите IL. Теперь у вас есть точные вызовы, которые нужно добавить в свой динамический метод. Просто следуйте примеру MSDN, отключив IL из примера для кода ваших отраженных методов.

После создания динамические методы вызываются примерно с той же скоростью, что и скомпилированные (видел тест, в котором динамические методы могли быть вызваны за ~ 20 мс, где отражение занимало более 200 мс).

Теперь у вас есть точные вызовы, которые нужно добавить в свой динамический метод. Просто следуйте примеру MSDN, отключив IL из примера для кода ваших отраженных методов.

После создания динамические методы вызываются примерно с той же скоростью, что и скомпилированные (видел тест, в котором динамические методы могли быть вызваны за ~ 20 мс, где отражение занимало более 200 мс).

Теперь у вас есть точные вызовы, которые нужно добавить в свой динамический метод. Просто следуйте примеру MSDN, отключив IL из примера для кода ваших отраженных методов.

После создания динамические методы вызываются примерно с той же скоростью, что и скомпилированные (видел тест, в котором динамические методы могли быть вызваны за ~ 20 мс, где отражение занимало более 200 мс).

8
ответ дан 8 December 2019 в 04:31
поделиться

Ваш вопрос довольно неясен, но вы, безусловно, можете использовать деревья выражений для динамического создания делегатов во время выполнения. (Есть и другие способы сделать это, например CodeDOM, но деревья выражений удобнее , если они делают все, что вам нужно. Однако существуют значительные ограничения на то, что вы можете делать.)

Часто проще однако используйте лямбда-выражение с некоторыми захваченными переменными.

Например, чтобы создать функцию, которая добавит указанное количество к любому целому числу, вы можете написать:

static Func<int, int> CreateAdder(int amountToAdd)
{
    return x => x + amountToAdd;
}

...
var adder = CreateAdder(10);
Console.WriteLine(adder(5)); // Prints 15

Если это не помогает, поясните, пожалуйста, свой вопрос.

5
ответ дан 8 December 2019 в 04:31
поделиться

Not that I am recommending this over the other better options, but there is a 7th method and thats to use AssemblyBuilder,ModuleBuilder,TypeBuilder, and MethodBuilder in the System.Reflection.Emit namespace to create a dynamic assembly. This is the same similar voodoo as using DynamicMethod.

For example you could use these to, at runtime, create a proxy class for a type and override virtual methods on that type.

To get you started here is some code...

using System;
using System.Reflection;
using System.Reflection.Emit;

var myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
        new AssemblyName("Test"), AssemblyBuilderAccess.RunAndSave);
var myModule = myAssembly.DefineDynamicModule("Test.dll");
var myType = myModule.DefineType("ProxyType", TypeAttributes.Public | TypeAttributes.Class,
                        typeof(TypeToSeverelyModifyInAnUglyWayButItsNecessary));
var myMethod = myType.DefineMethod("MethodNameToOverride", 
                        MethodAttributes.HideBySig | MethodAttributes.Public,
                        typeof(void),Type.EmptyTypes);
var myIlGenerator = myMethod.GetILGenerator();
myIlGenerator.Emit(OpCodes.Ret);
var type = myType.CreateType();
3
ответ дан 8 December 2019 в 04:31
поделиться

If you declare the method as virtual, you might be able to use Castle's DynamicProxy to substitute a dynamically-generated (with one of the other answer's methods) implementation at runtime:

Castle DynamicProxy is a library for generating lightweight .NET proxies on the fly at runtime. Proxy objects allow calls to members of an object to be intercepted without modifying the code of the class. Both classes and interfaces can be proxied, however only virtual members can be intercepted.

0
ответ дан 8 December 2019 в 04:31
поделиться

The second paragraph in your question suggests that really what you might be after is straightforward IOC (Inversion of Control)

Instead of declaring an instance of your class, you declare an instance of an interface and based on whatever condition you choose, you use the particular overriding class with the correct method in it. Hope that makes sense.

0
ответ дан 8 December 2019 в 04:31
поделиться

Вы должны сначала проверить, можно ли решить вашу проблему с помощью простого полиморфизма. Если вы не определяете абстрактную совместимость с другим языком или не редактируете компилятор, попытка изменить метод во время выполнения, вероятно, является неправильным решением проблемы.

0
ответ дан 8 December 2019 в 04:31
поделиться

You have several ways how to do it:

9
ответ дан 8 December 2019 в 04:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: