New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetInterfaceMap: System.Reflection vs IKVM.Reflection #5

Closed
markusjohnsson opened this Issue Mar 21, 2014 · 5 comments

Comments

Projects
None yet
3 participants
@markusjohnsson

Is this the right place to report IKVM.Reflection issues?

I've found a difference between System.Reflection (.NET 4.5) and IKVM.Reflection (nuget package and ikvm-fork master) in the behavior of Type.GetInterfaceMap(Type).

I don't know if it is intentional or not, but I suspect that it is IKVM.Reflection that gets this wrong.

The issue is demonstrated by the code below. Compile into IkvmInterfaceTest.exe and run. The output on the two rows should not differ.

using IKVM.Reflection;
using System;
using System.Linq;

namespace IkvmInterfaceTest
{
    public interface I
    {
        int Turn();
    }

    public class A : I
    {
        public virtual int Turn() { return 3; } 
    }

    public class B : A
    {
        public override int Turn() { return 4; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IkvmReflection();
            SystemReflection();

            Console.ReadLine();
        }

        private static void SystemReflection()
        {
            var b = typeof(B);
            var iface = typeof(I);
            var map = b.GetInterfaceMap(iface);

            Console.WriteLine("{0} {1}", map.InterfaceMethods[0].MetadataToken, map.TargetMethods[0].MetadataToken);
        }

        private static void IkvmReflection()
        {
            var u = new Universe();
            var asm = u.LoadFile("IkvmInterfaceTest.exe");
            var b = asm.GetType("IkvmInterfaceTest.B");
            var iface = asm.GetType("IkvmInterfaceTest.I");
            var map = b.GetInterfaceMap(iface);

            Console.WriteLine("{0} {1}", map.InterfaceMethods[0].MetadataToken, map.TargetMethods[0].MetadataToken);
        }
    }
}
@jfrijters

This comment has been minimized.

Show comment
Hide comment
@jfrijters

jfrijters Mar 21, 2014

This is indeed a bug. Thanks!
I'll probably fix this in a couple of days.

This is indeed a bug. Thanks!
I'll probably fix this in a couple of days.

@jfrijters

This comment has been minimized.

Show comment
Hide comment
@jfrijters

jfrijters Mar 22, 2014

This is now fixed in upstream (ikvm project in SourceForce cvs).

This is now fixed in upstream (ikvm project in SourceForce cvs).

@markusjohnsson

This comment has been minimized.

Show comment
Hide comment
@markusjohnsson

markusjohnsson Mar 22, 2014

Great, thanks!

Great, thanks!

@markusjohnsson

This comment has been minimized.

Show comment
Hide comment
@markusjohnsson

markusjohnsson Mar 26, 2014

I have a nearly identical test that also fails using the 7.4.5196 binary ("override" changed to "new" and interface redeclared in derived class):

using IKVM.Reflection;
using System;
using System.Linq;

namespace IkvmInterfaceTest
{
    public interface I
    {
        int Turn();
    }

    public class A : I
    {
        public virtual int Turn() { return 3; } 
    }

    public class B : A, I
    {
        public new int Turn() { return 4; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IkvmReflection();
            SystemReflection();

            Console.ReadLine();
        }

        private static void SystemReflection()
        {
            var b = typeof(B);
            var iface = typeof(I);
            var map = b.GetInterfaceMap(iface);

            Console.WriteLine("{0} {1}", map.InterfaceMethods[0].MetadataToken, map.TargetMethods[0].MetadataToken);
        }

        private static void IkvmReflection()
        {
            var u = new Universe();
            var asm = u.LoadFile("IkvmInterfaceTest.exe");
            var b = asm.GetType("IkvmInterfaceTest.B");
            var iface = asm.GetType("IkvmInterfaceTest.I");
            var map = b.GetInterfaceMap(iface);

            Console.WriteLine("{0} {1}", map.InterfaceMethods[0].MetadataToken, map.TargetMethods[0].MetadataToken);
        }
    }
}

I have a nearly identical test that also fails using the 7.4.5196 binary ("override" changed to "new" and interface redeclared in derived class):

using IKVM.Reflection;
using System;
using System.Linq;

namespace IkvmInterfaceTest
{
    public interface I
    {
        int Turn();
    }

    public class A : I
    {
        public virtual int Turn() { return 3; } 
    }

    public class B : A, I
    {
        public new int Turn() { return 4; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IkvmReflection();
            SystemReflection();

            Console.ReadLine();
        }

        private static void SystemReflection()
        {
            var b = typeof(B);
            var iface = typeof(I);
            var map = b.GetInterfaceMap(iface);

            Console.WriteLine("{0} {1}", map.InterfaceMethods[0].MetadataToken, map.TargetMethods[0].MetadataToken);
        }

        private static void IkvmReflection()
        {
            var u = new Universe();
            var asm = u.LoadFile("IkvmInterfaceTest.exe");
            var b = asm.GetType("IkvmInterfaceTest.B");
            var iface = asm.GetType("IkvmInterfaceTest.I");
            var map = b.GetInterfaceMap(iface);

            Console.WriteLine("{0} {1}", map.InterfaceMethods[0].MetadataToken, map.TargetMethods[0].MetadataToken);
        }
    }
}
@jfrijters

This comment has been minimized.

Show comment
Hide comment
@jfrijters

jfrijters Mar 27, 2014

Fixed in upstream cvs. Thanks!

Fixed in upstream cvs. Thanks!

gluck pushed a commit to gluck/ikvm that referenced this issue Oct 29, 2014

borgdylan pushed a commit to borgdylan/ikvm-fork that referenced this issue Apr 7, 2015

jfrijters
Bug fix. Type.GetInterfaceMap() should return overriden methods for i…
…nterface methods implemented by base classes.

mono#5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment