This question is somewhat an illustration to a related post, I believe the example below describes the essence of the problem.
class Program
{
public static IList<string> GetData(string arg)
{
return new string[] {"a", "b", "c"};
}
static void Main(string[] args)
{
var arg1 = "abc";
var res1 = GetData(arg1);
Console.WriteLine(res1.Count());
dynamic arg2 = "abc";
var res2 = GetData(arg2);
try
{
Console.WriteLine(res2.Count());
}
catch (RuntimeBinderException)
{
Console.WriteLine("Exception when accessing Count method");
}
IEnumerable<string> res3 = res2;
Console.WriteLine(res3.Count());
}
}
Isn't it bad that the second call to GetData raises exception only because GetData received a parameter cast to dynamic? The method itself is fine with such argument: it treats it as a string and returns correct result. But result is then cast to dynamic again, and suddenly result data can not be treated according to its underlying type. Unless it's explicitly cast back to a static type, as we see in the last lines of the example.
I failed to understand why it had to be implemented this way. It breaks interoperability between static and dynamic types. Once dynamic is used, it kind of infects the rest of the call chain potentially causing problems like this one.
UPDATE. Some people pointed out that Count() is an extension method, and it makes sense that it's not recognized. Then I changed a call res2.Count() to res2.Count (from an extension method to a property of Ilist), but the program raised the same exception in the same place! Now that is strange.
UPDATE2. flq pointed to Eric Lippert's blog posts on this topic, and I believe this post gives sufficient reasoning for why it is implemented this way: http://blogs.msdn.com/b/ericlippert/archive/2012/10/22/a-method-group-of-one.aspx