Создать делегат с аргументами, тип которых передан в виде строк

Рейтинг: 1Ответов: 1Опубликовано: 16.08.2023

Нужно создать делегат с указанным типом возврата и аргументов (ОБЯЗАТЕЛЬНО в виде строк)

пример: CreateDelegate("int", new string[]{"string", "bool", "bool"});

public static ??? CreateDelegate(string returnType, string[] arguments){ 
    //создать делегат 
}

Ответы

▲ 1Принят

Всем спасибо, решение было найдено.
Код на GitHub: https://github.com/nekit270ch/dllcaller

Метод CreateDelegate(string returnType, string[] argumentTypes) создает сборку с помощью AssemblyBuilder. В ней с помощью TypeBuilder, ConstructorBuilder и MethodBuilder создается тип делегата с указанными типом возврата и аргументов. Строки конвертируются в типы через Type.GetType.

Полный код метода:

private static Type CreateDelegate(string returnType, string[] argumentTypes){
    Type delegateReturnType = Type.GetType(returnType);

    Type[] delegateArgumentTypes = new Type[argumentTypes.Length];
    for(int i = 0; i < argumentTypes.Length; i++){
        delegateArgumentTypes[i] = Type.GetType(argumentTypes[i]);
    }

    AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
    AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");

    TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicDelegate", TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class, typeof(MulticastDelegate));

    ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(object), typeof(IntPtr) });
    constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);

    MethodBuilder methodBuilder = typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, delegateReturnType, delegateArgumentTypes);
    methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);

    Type delegateType = typeBuilder.CreateType();
    return delegateType;
}