103

I am going to summarize my problem into the following code snippet.

List<int> list = new List<int>() { 5, 56, 2, 4, 63, 2 };
Console.WriteLine(list.First());

Above code is working fine.

Now I tried the following

dynamic dList = list;
 Console.WriteLine(dList.First());

but I am getting RuntimeBinderException.Why is it so?

svick
  • 236,525
  • 50
  • 385
  • 514
santosh singh
  • 27,666
  • 26
  • 83
  • 129
  • This seems like a duplicate of this question asked just 4 days ago http://stackoverflow.com/questions/5270782/how-to-call-an-extension-method-of-a-dynamic-type – jbtule Mar 15 '11 at 16:17
  • @jbtule The difference is that the `this` is dynamic here, but if you land here, you should probably look at that question too – nik.shornikov Nov 23 '12 at 21:22
  • Almost this [will-the-dynamic-keyword-in-c4-support-extension-methods](http://stackoverflow.com/questions/258988/will-the-dynamic-keyword-in-c4-support-extension-methods) – nawfal Feb 03 '14 at 14:57

3 Answers3

150

To expand on Jon's answer, the reason this doesn't work is because in regular, non-dynamic code extension methods work by doing a full search of all the classes known to the compiler for a static class that has an extension method that matches. The search goes in order based on the namespace nesting and available using directives in each namespace.

That means that in order to get a dynamic extension method invocation resolved correctly, somehow the DLR has to know at runtime what all the namespace nestings and using directives were in your source code. We do not have a mechanism handy for encoding all that information into the call site. We considered inventing such a mechanism, but decided that it was too high cost and produced too much schedule risk to be worth it.

Maxwell175
  • 1,954
  • 1
  • 17
  • 27
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 3
    Is such a feature in the offing? It would certainly be a breaking change; calls currently throwing RunTimeBinderExceptions would suddenly start working upon recompiling source. Also, would there be any security risks associated with implementing such a feature? – Ani Mar 15 '11 at 23:45
  • 5
    @ani: **Are we planning on implementing that feature?** No. **Are there any security risks?** I am not aware of any; what sort of security risk did you have in mind? Start by saying who is the attacker and what threat they are making to the user. – Eric Lippert Feb 01 '12 at 16:08
  • @EricLippert, I have understood that all `dynamic` objects are equal to C#: `DynamicObject`, so there is no way to differentiate them and is one of the reasons why is not possible add extension methods to `dynamic`, that's right? – Tomas Ramirez Sarduy Oct 28 '12 at 17:25
  • @EricLippert consider to expand this answer a bit more and add sentence along the lines of "When *any* of the parameters are dynamic, then all resolutions are deferred until run-time". While it obvious to you this important bit is hard to find anywhere else on SO (see https://stackoverflow.com/questions/48324768/ for example) – Alexei Levenkov Jan 18 '18 at 16:12
  • @AlexeiLevenkov: Though perfectly valid, that point has nothing to do with *this question*, which is narrowly about extension methods. If you feel that it is important that there be a canonical answer on SO that has the information you mentioned, and there's no existing question that fits, I'd suggest you post a new question that specifically addresses that scenario. – Eric Lippert Jan 18 '18 at 16:19
  • @AlexeiLevenkov: That said, it's not clear to me why you think this point hasn't been adequately covered. https://stackoverflow.com/questions/14185990/dynamic-operator-resolution/14189961#14189961 comes to mind. As does https://stackoverflow.com/questions/9382130/why-does-a-method-invocation-expression-have-type-dynamic-even-when-there-is-onl/9385449#9385449 – Eric Lippert Jan 18 '18 at 16:20
  • I know that there are enough explanations (and I could have found that as I do know answer myself :) ), my concern is that other people are unlikely to make connection between "one argument passed as dynamic" and whole invocation becoming run-time at that point. If I would not know the answer I don't know how to get from "C# extension dynamic" or "C# extension C1973" that leads to this answer and the one you've linked. – Alexei Levenkov Jan 18 '18 at 16:27
141

To expand on Stecya's answer... extension methods aren't supported by dynamic typing in the form of extension methods, i.e. called as if they were instance methods. However, this will work:

dynamic dList = list;
Console.WriteLine(Enumerable.First(dList));

Of course, that may or may not be useful. If you could give more information about why and how you're trying to use dynamic typing, we may be able to help more.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I was playing with dynamic object and got this exception.Do you have written any article on this topic, where to use or not use dynamic object – santosh singh Mar 15 '11 at 12:27
  • 20
    @geek: Personally my rule of thumb is only to use `dynamic` where you really need to... basically if you would otherwise be accessing members with reflection, that's a big sign. On the other hand, I'm a die-hard static typer - others may suggest less pessimistic policies :) – Jon Skeet Mar 15 '11 at 12:36
  • 2
    It might be more readable to cast back to the know type, this works: Console.WriteLine(((List)dList).First()); Or Console.WriteLine((dList as List).First());. – AVee Jun 18 '19 at 13:46
20

Because First() is not a method of List. It is defined in Linq Extension to IEnumerable<>

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Stecya
  • 22,896
  • 10
  • 72
  • 102