Markus Gilli
Markus Gilli

Reputation: 237

Why is a method of a interface not found by C# dynamic on internal classes?

I tried to use dynamic to access methods of classes that are located in another assembly. These classes are internal and created by builders that return a public interface. For some reason dynamic is not able to invoke the method defined on the interface. I can use "classic" reflection to get the code running but I don't understand why it's not working with dynamic.

I know that dynamic is not working with methods of internal classes but here we have a public interface. So please can someone explain why dynamic throws the RuntimeBinderException in the example below?

    namespace SandboxLib  // located in SandboxLib.dll
    {
        public class InternalBuilder
        {
            public static IInterface Build()
            {
                return new InternalClass();
            }
        }

        public interface IInterface
        {
            void IfMethod();
        }
        
        internal class InternalClass : IInterface
        {
            public void IfMethod() { }
        }
    }

    namespace Sandbox  // located in Sandbox.dll
    {
        public class Program
        {
            static void Main(string[] args)
            {
                var inst = InternalBuilder.Build();
                dynamic dynInst = inst;

                inst.IfMethod();     // ok
                dynInst.IfMethod();  // Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'IfMethod'
            }
        }
    }

Upvotes: 5

Views: 792

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109597

This behaviour is described in the C# Standard:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#dynamic-binding

Under "Member Lookup" it states:

Member lookup considers not only the name of a member but also the number of type parameters the member has and whether the member is accessible.

Since the member IfMethod() that the dynamic resolution has found is internal, the call will fail, as per the specification.

Upvotes: 2

Related Questions