The following code demonstrates my question:
public class DynamicExample
{
public void DoSomething()
{
var x = new ExpandoObject();
dynamic d = x;
d.GetString = (Func<string>)(() => "Some Value");
d.GetString().SomeStringExtension(); // Doesn't work - expected
((string)d.GetString()).SomeStringExtension(); // Works - expected
Build(d).SomeStringExtension(); // Doesn't work - unexpected?
}
private static string Build(dynamic d)
{
return (string)d.GetString();
}
}
public static class StringExtensions
{
public static int SomeStringExtension(this string s)
{
return s.Length;
}
}
The question is, why is there a difference for the compiler between casting the type inline to the extension method call and moving that cast out into a separate method?
Build(d)
is still a dynamic expression - the compile-time type of the method is dynamic
even though you can see exactly what's going on. That means extension methods won't work.
Basically the compiler follows reasonably simple rules to determine what the type of an expression is, and almost any expression involving dynamic
ends up being considered as a dynamic expression. The exceptions to this are:
d is SomeType
(always considered to be bool
)as
That's it as far as I can remember, although I could be mistaken...
Now the language could have been designed such that this case would statically resolve the call to Build
as the only sensible one - after all, it's impossible for d
to be of any type which would change which method is called - but to specify the exact rules for that would make the language specification (and the compiler) significantly more complicated for relatively little gain.
If you hover over Build(d)
in VS2010, you'll see that the entire expression is considered dynamic, and to be resolved at run-time. As such, it can't bind to the extension method (which would otherwise occur at compile-time.)
The reason the whole expression is dynamic
is that without knowing the compile-time type of the argument, overload resolution can't be isn't performed, and so the return-type of the method can't be isn't known either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With