Hello out there,

 

I’ve come across an issue with calling a method of an instance which ends up being an explicitly implemented interface method. Let me explain with a very brief example:

 

Consider this a very basic interface:

 

[File: ISomeInterface.cs]

namespace PythonInterfaceCalls

{

    public interface ISomeInterface

    {

        void ImplicitImplementation();

        void ExplicitImplementation();

    }

}

 

And here’s an implementing class. Note one of the methods being implicitly implemented, the other being explicitly implemented:

 

[File: SomeImplementation.cs]

using System;

 

namespace PythonInterfaceCalls

{

    public class SomeImplementation: ISomeInterface

    {

        public void ImplicitImplementation()

        {

            Console.WriteLine("Call of implicitly implemented interface method.");

        }

 

        void ISomeInterface.ExplicitImplementation()

        {

            Console.WriteLine("Call of explicitly implemented interface method.");

        }

    }

}

 

Note the method headers. While the implicit implementation is (and has to be) public, the explicit implementation is (and has to be) internal. Both methods work well in C# (as long as the instance is casted into the interface type). See the unit tests, both passing:

 

[File: TestImplementation.cs]

using System;

using System.IO;

using NUnit.Framework;

 

namespace PythonInterfaceCalls

{

    [TestFixture]

    public class TestImplementation

    {

        [Test]

        public void TestImplicitCall()

        {

            var implementation = new SomeImplementation() as ISomeInterface;

            using (StringWriter sw = new StringWriter())

            {

                Console.SetOut(sw);

                implementation.ImplicitImplementation();

                Assert.AreEqual("Call of implicitly implemented interface method.\r\n", sw.ToString());

            }

        }

 

        [Test]

        public void TestExplicitCall()

        {

            var implementation = new SomeImplementation() as ISomeInterface;

            using (StringWriter sw = new StringWriter())

            {

                Console.SetOut(sw);

                implementation.ExplicitImplementation();

                Assert.AreEqual("Call of explicitly implemented interface method.\r\n", sw.ToString());

            }

        }

    }

}

 

This should be solvable using the following method to access all interface members, not just the publicly available ones:

 

[File: InterfaceMembersExtension.cs]

using System;

using System.Collections.Generic;

using System.Reflection;

 

namespace PythonInterfaceCalls

{

    public static class InterfaceMembersExtension

    {

        public static IList<MethodInfo> GetImplementedMethods(this Type targetType, Type interfaceType)

        {

            return targetType.GetInterfaceMap(interfaceType).TargetMethods;

        }

    }

}

 

Please find the complete solution attached to this mail.

 

Is there a chance that this will be implemented in PythonNet?

 

Thanks in advance,

 

Hennnig