Hi Alex

Dude, you are a legend! That worked ... :)

Thanks

~G

On 21 February 2011 20:11, Alex Corrado <[email protected]> wrote:

> I might be wrong, but I think you are trying to call the unspecialized
> generic method directly. You need to instantiate it with type
> arguments. Instead of calling renamedMethod directly, add the
> extension method somewhere, and try something like:
>
> il.Emit(OpCodes.Call, renamedMethod.MakeGeneric
> (methodThatShouldReplaceOriginal.GenericParameters.ToArray ()));
>
>                public static MethodReference MakeGeneric (this
> MethodReference
> method, params TypeReference [] args)
>                {
>                        if (args.Length == 0)
>                                return method;
>
>                        if (method.GenericParameters.Count != args.Length)
>                                throw new ArgumentException ("Invalid number
> of generic type
> arguments supplied");
>
>                        var genericTypeRef = new GenericInstanceMethod
> (method);
>                        foreach (var arg in args)
>                                genericTypeRef.GenericArguments.Add (arg);
>
>                        return genericTypeRef;
>                }
>
> Hope this helps!
>
> -Alex
>
> On Mon, Feb 21, 2011 at 11:28 AM, Gavin van der Merwe
> <[email protected]> wrote:
> > Thanks for the quick response ... I am sure it is something silly that I
> > have missed.
> > Given class:
> >     public class ClassWithClonedMethod
> >     {
> >         public void GenericMethod<T>()
> >         {
> >             //return default(T);
> >         }
> >         public void CallToGenericMethod<T>()
> >         {
> >             GenericMethod<T>();
> >         }
> >     }
> > And test(NOT):
> >         [Test]
> >         public void should_emit_call_to_generic_properly()
> >         {
> >             var assembly =
> > AssemblyDefinition.ReadAssembly("TestAssembly.dll");
> >             var type = assembly.MainModule.Types.Where(t => t.Name ==
> > "ClassWithClonedMethod").First();
> >             var renamedMethod = type.Methods.Where(m => m.Name ==
> > "GenericMethod").First();
> >             // Create new method
> >             var methodThatShouldReplaceOriginal = new
> > MethodDefinition(renamedMethod.Name, renamedMethod.Attributes,
> > renamedMethod.ReturnType);
> >
> >
>  renamedMethod.DeclaringType.Methods.Add(methodThatShouldReplaceOriginal);
> >             // Rename existing method
> >             renamedMethod.Name = string.Format("{0}_Clone",
> > renamedMethod.Name);
> >             // Copy vars and stuff
> >             methodThatShouldReplaceOriginal.CallingConvention =
> > renamedMethod.CallingConvention;
> >             methodThatShouldReplaceOriginal.SemanticsAttributes =
> > renamedMethod.SemanticsAttributes;
> >             renamedMethod.CustomAttributes.ToList().ForEach(a =>
> > methodThatShouldReplaceOriginal.CustomAttributes.Add(a));
> >             renamedMethod.SecurityDeclarations.ToList().ForEach(s =>
> > methodThatShouldReplaceOriginal.SecurityDeclarations.Add(s));
> >             methodThatShouldReplaceOriginal.IsAbstract =
> > renamedMethod.IsAbstract;
> >             methodThatShouldReplaceOriginal.IsAddOn =
> renamedMethod.IsAddOn;
> >             methodThatShouldReplaceOriginal.IsAssembly =
> > renamedMethod.IsAssembly;
> >             methodThatShouldReplaceOriginal.IsCheckAccessOnOverride =
> > renamedMethod.IsCheckAccessOnOverride;
> >             methodThatShouldReplaceOriginal.IsCompilerControlled =
> > renamedMethod.IsCompilerControlled;
> >             methodThatShouldReplaceOriginal.IsFamily =
> > renamedMethod.IsFamily;
> >             methodThatShouldReplaceOriginal.IsFamilyAndAssembly =
> > renamedMethod.IsFamilyAndAssembly;
> >             methodThatShouldReplaceOriginal.IsFamilyOrAssembly =
> > renamedMethod.IsFamilyOrAssembly;
> >             methodThatShouldReplaceOriginal.IsFinal =
> renamedMethod.IsFinal;
> >             methodThatShouldReplaceOriginal.IsFire =
> renamedMethod.IsFire;
> >             methodThatShouldReplaceOriginal.IsForwardRef =
> > renamedMethod.IsForwardRef;
> >             methodThatShouldReplaceOriginal.IsGetter =
> > renamedMethod.IsGetter;
> >             methodThatShouldReplaceOriginal.IsHideBySig =
> > renamedMethod.IsHideBySig;
> >             methodThatShouldReplaceOriginal.IsIL = renamedMethod.IsIL;
> >             methodThatShouldReplaceOriginal.IsInternalCall =
> > renamedMethod.IsInternalCall;
> >             methodThatShouldReplaceOriginal.IsManaged =
> > renamedMethod.IsManaged;
> >             methodThatShouldReplaceOriginal.IsNative =
> > renamedMethod.IsNative;
> >             methodThatShouldReplaceOriginal.IsNewSlot =
> > renamedMethod.IsNewSlot;
> >             methodThatShouldReplaceOriginal.IsPInvokeImpl =
> > renamedMethod.IsPInvokeImpl;
> >             methodThatShouldReplaceOriginal.IsPreserveSig =
> > renamedMethod.IsPreserveSig;
> >             methodThatShouldReplaceOriginal.IsPrivate =
> > renamedMethod.IsPrivate;
> >             methodThatShouldReplaceOriginal.IsPublic =
> > renamedMethod.IsPublic;
> >             methodThatShouldReplaceOriginal.IsRemoveOn =
> > renamedMethod.IsRemoveOn;
> >             methodThatShouldReplaceOriginal.IsReuseSlot =
> > renamedMethod.IsReuseSlot;
> >             methodThatShouldReplaceOriginal.IsRuntime =
> > renamedMethod.IsRuntime;
> >             methodThatShouldReplaceOriginal.IsRuntimeSpecialName =
> > renamedMethod.IsRuntimeSpecialName;
> >             methodThatShouldReplaceOriginal.IsSetter =
> > renamedMethod.IsSetter;
> >             methodThatShouldReplaceOriginal.IsSpecialName =
> > renamedMethod.IsSpecialName;
> >             methodThatShouldReplaceOriginal.IsStatic =
> > renamedMethod.IsStatic;
> >             methodThatShouldReplaceOriginal.IsSynchronized =
> > renamedMethod.IsSynchronized;
> >             methodThatShouldReplaceOriginal.IsUnmanaged =
> > renamedMethod.IsUnmanaged;
> >             methodThatShouldReplaceOriginal.IsUnmanagedExport =
> > renamedMethod.IsUnmanagedExport;
> >             methodThatShouldReplaceOriginal.IsVirtual =
> > renamedMethod.IsVirtual;
> >             methodThatShouldReplaceOriginal.NoInlining =
> > renamedMethod.NoInlining;
> >             methodThatShouldReplaceOriginal.NoOptimization =
> > renamedMethod.NoOptimization;
> >             // Copy parameters across
> >             if (renamedMethod.HasParameters)
> >                 foreach (var parameter in
> renamedMethod.Parameters.ToList())
> >
> >  methodThatShouldReplaceOriginal.Parameters.Add(parameter);
> >
> >             // Copy generic parameters across
> >             if (renamedMethod.HasGenericParameters)
> >             {
> >                 foreach (var genericParameter in
> > renamedMethod.GenericParameters.ToList())
> >                 {
> >                     if (genericParameter != null)
> >                     {
> >                         var newGenericParameter = new
> > GenericParameter(genericParameter.Name, methodThatShouldReplaceOriginal);
> >
> >
>  methodThatShouldReplaceOriginal.GenericParameters.Add(newGenericParameter);
> >                         newGenericParameter.Attributes =
> > genericParameter.Attributes;
> >                         genericParameter.Constraints.ForEach(gp =>
> > newGenericParameter.Constraints.Add(gp));
> >                         genericParameter.CustomAttributes.ForEach(ca =>
> > newGenericParameter.CustomAttributes.Add(ca));
> >                         newGenericParameter.DeclaringType =
> > genericParameter.DeclaringType;
> >                         genericParameter.GenericParameters.ForEach(gp =>
> > newGenericParameter.GenericParameters.Add(gp));
> >
>  newGenericParameter.HasDefaultConstructorConstraint
> > = genericParameter.HasDefaultConstructorConstraint;
> >                         newGenericParameter.IsContravariant =
> > genericParameter.IsContravariant;
> >                         newGenericParameter.IsCovariant =
> > genericParameter.IsCovariant;
> >                         newGenericParameter.IsNonVariant =
> > genericParameter.IsNonVariant;
> >                     }
> >                 }
> >             }
> >             // Get IL processor and emit call to renamed clone
> >             var il =
> methodThatShouldReplaceOriginal.Body.GetILProcessor();
> >             il.Emit(OpCodes.Ldarg_0);
> >             il.Emit(OpCodes.Call, renamedMethod);
> >             il.Emit(OpCodes.Ret);
> >             assembly.Write("Foo.dll");
> >         }
> >
> > Yields:
> > .method public hidebysig instance void  GenericMethod<T>() cil managed
> > {
> >   // Code size       7 (0x7)
> >   .maxstack  8
> >   IL_0000:  ldarg.0
> >   IL_0001:  call       instance void
> >
> CryoAOP.TestAssembly.TypeThatShouldBeIntercepted::GenericMethod_Clone<[1]>()
> >   IL_0006:  ret
> > } // end of method TypeThatShouldBeIntercepted::GenericMethod
> > Where I am expecting:
> > .method public hidebysig instance void  GenericMethod<T>() cil managed
> > {
> >   // Code size       7 (0x7)
> >   .maxstack  8
> >   IL_0000:  ldarg.0
> >   IL_0001:  call       instance void
> >
> CryoAOP.TestAssembly.TypeThatShouldBeIntercepted::GenericMethod_Clone<!!0>()
> >   IL_0006:  ret
> > } // end of method TypeThatShouldBeIntercepted::GenericMethod
> >
> > What do you guys think?
> > On 21 February 2011 13:59, Raph <[email protected]> wrote:
> >>
> >> to me it looks like you are missing the genericarguments.
> >>
> >> but as jb said, posting your code would help ;)
> >>
> >> --
> >> --
> >> mono-cecil
> >
> > --
> > --
> > mono-cecil
>

-- 
--
mono-cecil

Reply via email to