The problem is that Count is an extension method.
How to find extension methods at runtime? The information about what is βin scopeβ is based on the βuseβ operations in the specific file being compiled. However, they are not included in compiled code at runtime. Should he look at all the possible extension methods in all loaded assemblies? What about assemblies referenced by the project but not yet loaded? There are an amazing number of boundary cases that arise when trying to dynamically use extension methods.
The correct solution in this case is to call the static method in its form without extension:
Enumerable.Count(res2)
Or, since you know this IList<T> in this case, just use the Count property:
res2.Count & lt --- --- EDIT: This does not work because it is an explicitly implemented property of the interface when implemented by an array.
Once again, looking at your question, I see that the real question is not in resolving the extension method as such, but in why it cannot determine that there is a single method resolution, and therefore know the type statically. I should think about this a bit more, but I assume this is a similar question about boundary cases, especially after you start looking at multiple overloads.
Here is one unpleasant boundary case that may arise in the general case (although it does not apply directly to your case, since you exit Object).
Suppose you have a Base class in assembly A. There is also a Derived: Base class in assembly B. In the Derived class, you have the code above, and you think there is only one possible resolution for GetData. However, now suppose that a new version of assembly A is published, which has a secure GetData method with a different signature. Your derived class inherits this, and DLR dutifully allows dynamic binding to this new method. Suddenly, the return type may not be what you expected. Please note that all this can happen if you do not recompile assembly B. This means that the compiler cannot begin to assume that DLR will be allowed to the type, which, according to the predictor, is the only option, since the dynamic environment during runtimes may give a different type.