public Type CreateCustomDelegate(Type returnType, params Type[] parameterTypes)
{
AssemblyName assembly = new AssemblyName();
assembly.Name = "CreateCustomDelegateAssembly";
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("TempModule");
TypeBuilder typeBuilder =
moduleBuilder.DefineType("TempDelegateType",
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class |
TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof (MulticastDelegate));
ConstructorBuilder constructorBuilder =
typeBuilder.DefineConstructor(
MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public,
CallingConventions.Standard, new Type[] {typeof (object), typeof (int)});
constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
MethodBuilder methodBuilder =
typeBuilder.DefineMethod("Invoke",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot |
MethodAttributes.Virtual, returnType, parameterTypes);
methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime);
return typeBuilder.CreateType();
}
[Test]
public void WithCustomDelegate()
Dictionary<string, object> context = new Dictionary<string, object>();
context.Add("user", "alex");
context.Add("age", 26);
Proc testCore = delegate
List<string> parameters = new List<string>(context.Keys);
List<object> values = new List<object>(context.Values);
PythonEngine engine = new PythonEngine();
Type[] parameterTypes = new Type[context.Count];
for (int i = 0; i < parameterTypes.Length; i++) parameterTypes[i] = typeof (object);
Type delegateType = CreateCustomDelegate(typeof (object), parameterTypes);
Type pythonEngine = typeof (PythonEngine);
MethodInfo genericMethod =
pythonEngine.GetMethod("CreateMethod", new Type[] {typeof (string), typeof (IList<string>)});
MethodInfo method = genericMethod.MakeGenericMethod(delegateType);
object result =
method.Invoke(engine,
new object[] {"return user + ' is ' + str(age) + ' years old'", parameters});
Delegate myDelegate = (Delegate) result;
Assert.AreEqual("alex is 26 years old", myDelegate.DynamicInvoke(values.ToArray()));
};
// try it with our two keys in the dictionary
testCore();
// try it with another key in the dictionary
context.Add("monkey_colour", "brown");