Skip to content

Generic type parameters ignored in cache, wrong method invoked #21

@bacar

Description

@bacar

Hi,

The following test fails:

public class GenericTest
{
    static string Foo<T>() => typeof(T).FullName;

    [Test]
    public void Generic_type_params_respected()
    {
        MethodInfo x = typeof(GenericTest).GetMethod(nameof(Foo), BindingFlags.Static|BindingFlags.NonPublic);

        var gen1 = x.MakeGenericMethod(typeof(int));
        var gen2 = x.MakeGenericMethod(typeof(double));
        
        Assert.AreEqual(typeof(int).FullName, gen1.Call());
        Assert.AreEqual(typeof(double).FullName, gen2.Call());
    }
}
  Expected string length 13 but was 12. Strings differ at index 7.
  Expected: "System.Double"
  But was:  "System.Int32"
  ------------------^

The second call gen2.Call() ends up invoking the first method, with the wrong (int) type parameters.
The problem is reversed if you swap the two assert lines to make the double one come first.

        Assert.AreEqual(typeof(double).FullName, gen2.Call());
        Assert.AreEqual(typeof(int).FullName, gen1.Call());
  Expected string length 12 but was 13. Strings differ at index 7.
  Expected: "System.Int32"
  But was:  "System.Double"
  ------------------^

The problem appears to be in the MethodInvocationEmitter ctor - it passes null as the genericTypes argument to the CallInfo constructor, which means that the generic type arguments of the method are ignored when looking up an appropriate delegate from the BaseEmitter.cache

private MethodInvocationEmitter( Type targetType, Flags bindingFlags, string name, Type[] parameterTypes,
	                                 MemberInfo methodInfo )
        : base(new CallInfo(targetType, null, bindingFlags, MemberTypes.Method, name, parameterTypes, methodInfo, true))
	{
	}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions