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;
}
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.