Thank you! May be it can be added to HOWTOs? :)

On 19 май, 12:27, Gábor Kozár <[email protected]> wrote:
> 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