I think that Mono.Cecil identifies what to call based on the signature of
the reference (i.e. DeclaringType, Name, GenericParameters and Parameters).
A MethodReference is just that: a reference to a MethodDefinition with the
same signature. A MethodReference in itself does not represent a method, but
rather a reference to that method.

If you were to clone a MethodDefinition, you'd also have to copy the body.

2011/5/19 Stanislav <[email protected]>

> Thank you! Looks like a little bit strange )
>
> Do I understand correctly that the instantiated generic types should
> not be added to declaringtype?
>
> For ex., I cannot see method body copying, or adding resulting
> MethodReference to any type. It just called. Why?
>
>        public static MethodReference MakeHostInstanceGeneric(this
> MethodReference self, TypeReference type)
>        {
>            var m = new MethodReference(self.Name, self.ReturnType,
> type)
>            {
>                HasThis = self.HasThis,
>                ExplicitThis = self.ExplicitThis,
>                CallingConvention = self.CallingConvention
>            };
>            foreach (var p in self.Parameters)
>                m.Parameters.Add(new
> ParameterDefinition(p.ParameterType));
>            foreach (var p in self.GenericParameters)
>                m.GenericParameters.Add(p);
>
>            return m;
>        }
>
> Stanislav
>
> On 19 май, 10:42, seesharper <[email protected]> wrote:
> > I had a similar problem.
> >
> > Take a look at this discussion
> >
> > http://groups.google.com/group/mono-cecil/browse_thread/thread/9826ad...
> >
> > 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
>

-- 
--
mono-cecil

Reply via email to