I had a similar problem.

Take a look at this discussion

http://groups.google.com/group/mono-cecil/browse_thread/thread/9826ade54b91e3b2

Regards

Bernhard Richter

On May 18, 9:16 am, Stanislav <[email protected]> wrote:
> Hi!
>
> I cant understand, what I need to do to create generic type, emit
> creating and emit generic method call of newly created type. In my
> case I need to create delegate to generic method.
> My steps:
>
>    Create TypeDefinition of delegate extends MulticastDelegate
>
>             // Create new delegate type
>             var dlgtype = new
> TypeDefinition(method.DeclaringType.Namespace, method.Name +
> "_Delegate", TypeAttributes.Sealed | TypeAttributes.NestedAssembly,
> _MulticastDelegate);
>
>             delegateClass.NestedTypes.Add(dlgtype);
>
>    Copy all GenericParams from method to newly created TypeDefinition
>
>             if(method.DeclaringType.HasGenericParameters)
>             {
>                 method.DeclaringType.CopyGenericParametersTo(dlgtype);
>             }
>
>    Create .ctor
>
>             var constructor = new MethodDefinition(".ctor",
> MethodAttributes.Public | MethodAttributes.CompilerControlled |
> MethodAttributes.RTSpecialName | MethodAttributes.SpecialName |
> MethodAttributes.HideBySig, _Void);
>             dlgtype.Methods.Add(constructor);
>             constructor.Parameters.Add(new
> ParameterDefinition("'object'", ParameterAttributes.None, _Object));
>             constructor.Parameters.Add(new
> ParameterDefinition("'method'", ParameterAttributes.None, _IntPtr));
>             constructor.IsRuntime = true;
>
>    Create BeginInvoke using parameters types map (generic params from
> original method to generic params from delegate type)
>             var begininvoke = new MethodDefinition("BeginInvoke",
> methodAttributes, _IAsyncResult);
>             dlgtype.Methods.Add(begininvoke);
>             foreach(var para in template.Parameters)
>             {
>                 if (!para.ParameterType.IsGenericParameter)
>                 {
>                     begininvoke.Parameters.Add(new
> ParameterDefinition(para.Name, para.Attributes, para.ParameterType));
>                 }
>                 else
>                 {
>                     var type =
> dlgtype.GenericParameters.FirstOrDefault(p => p.Name ==
> para.ParameterType.Name);
>                     if(type != null)
>                     {
>                         begininvoke.Parameters.Add(new
> ParameterDefinition(para.Name, para.Attributes, type));
>                     }
>                 }
>             }
>             begininvoke.Parameters.Add(new
> ParameterDefinition("callback", ParameterAttributes.None,
> _AsyncCallback));
>             begininvoke.Parameters.Add(new
> ParameterDefinition("object", ParameterAttributes.None, _Object));
>             begininvoke.IsRuntime = true;
>    Create Iinvoke method
>             // ...
>
> Emit something like this:
>             worker.InsertBefore(fst,
> Instruction.Create(target.HasThis ? OpCodes.Ldarg_0 :
> OpCodes.Ldnull));
>             worker.InsertBefore(fst, Instruction.Create(OpCodes.Ldftn,
> duplicate));
>             worker.InsertBefore(fst,
> Instruction.Create(OpCodes.Newobj, constructor));
>             worker.InsertBefore(fst, Instruction.Create(OpCodes.Stloc,
> dupdlg));
> to create delegate
>
> BUT. When I try to create delegate, I get System.TypeLoadException.
> What's wrong?
>
> Thanks.

-- 
--
mono-cecil

Reply via email to