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

Reply via email to