0

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;
        }
rahulaga-msft
  • 3,964
  • 6
  • 26
  • 44
  • 1
    Coz Array does not have Count property. Array has Length property. try with `array.Length` and `dynamic` – Chetan Mar 17 '18 at 10:25
  • @ChetanRanpariya : code is working perfect when it is `ICollection` – rahulaga-msft Mar 17 '18 at 10:26
  • Yes.. coz ICollection has Count property. When you use dynamic, Array does not get converted to ICollection, compiler will try to use the properties which are specific to the type which is passed. And Array does not have Count property. https://stackoverflow.com/questions/4769971/why-does-c-sharp-array-not-have-count-property – Chetan Mar 17 '18 at 10:29
  • 1
    Array implements ICollection.Count property via explicit interface implementation that's why Count property is not available directly on Array. – Chetan Mar 17 '18 at 10:31

1 Answers1

1

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.

InBetween
  • 32,319
  • 3
  • 50
  • 90