Given this short example program:
static void Main(string[] args)
{
Console.WriteLine(Test("hello world"));
}
private static int Test(dynamic value)
{
var chars = Chars(value.ToString());
return chars.Count();
}
private static IEnumerable<char> Chars(string str)
{
return str.Distinct();
}
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''object' does not contain a definition for 'Count''
dynamic
chars
IEnumerable<char>
Chars
IEnumerable<char>
dynamic
With dynamic
, all method calls are resolved at runtime. Therefore, it declines to guess at compile time what method is actually being called when you call Chars()
, Count()
, or even ToString()
. It could be anything, returning anything. This is often called "dynamic contagion".
For all the compiler knows, somtimes value.ToString()
will return MyRandomPOCOClass
, and at runtime it'll be able to dig up some overload like Tuple<int,String> Chars(MyRandomPOCOClass x)
. Maybe next time value.ToString()
will return int
. All bets are off. dynamic
turns C# into a scripting language.
Here's an example of dynamic runtime overload behavior (here's a fiddle):
public static void Main()
{
dynamic x = "foo";
Test(x);
x = 34;
Test(x);
}
public static void Test(string s)
{
Console.WriteLine("String " + s);
}
public static void Test(int n)
{
Console.WriteLine("Int " + n);
}
Output:
String foo
Int 34