Search code examples
c#dynamicdynamic-language-runtime

RunTimeBinderException when passing int[] to method having parameter type dynamic


Below code work perfectly fine unless I change GetCount parameter type from ICollection to dynamic - it throws RuntimrBinderException Why at runtime Count property is not available ?

static void Main(string[] args)
        {
            var list = new int[] { 1, 2, 3 };
            var x = GetCount(list);
            Console.WriteLine(x);
        }
        private static int GetCount(ICollection array) /*changing array type to dynamic fails at runtime*/
        {
            return array.Count;
        }

Solution

  • The reason this fails is because in arrays, although they implement ICollection, Count is implemented explicitly. Explicitly implemented members can only be invoked through the interface typed reference.

    Consider the following:

    interface IFoo 
    {
        void Frob();
        void Blah();
    } 
    
    public class Foo: IFoo
    {
         //implicit implementation
         public void Frob() { ... }
    
         //explicit implementation
         void IFoo.Blah() { ... }
    }
    

    And now:

    var foo = new Foo();
    foo.Frob(); //legal
    foo.Blah(); //illegal
    var iFoo = foo as IFoo;
    iFoo.Blah(); //legal
    

    In your case, when the argument is typed ICollection, Count is a valid invocation, but when dynamic is used, the argument isn't implicitly converted to ICollection, it remains a int[] and Count is simply not invocable through that reference.