I have encountered issues with using dynamic variables in C#. This arose while coding NancyFx routing modules, but I have boiled down the issue to the example below. While I received a different exception in the original code, the example code still throws an exception that I believe is erroneous. Does anyone see what is going on here, or have others encountered similar problems?
Note that the following posts may be related: StackOverflowException when accessing member of generic type via dynamic: .NET/C# framework bug? System.Dynamic bug?
The code:
class Program
{
static void Main(string[] args)
{
var dictionary = new Dictionary<string, object>();
dictionary.Add("number", 12);
var result = MethodUsesExplicitDeclaration(dictionary);
var result2 = MethodUsesImplicitDeclaration(dictionary);
}
static dynamic MethodUsesExplicitDeclaration(dynamic reallyDictionary)
{
// this works, ostensibly because the local variable is explicitly declared
IDictionary<string, object> dictionary = CastDictionary(reallyDictionary);
return dictionary.Get<int>("number");
}
static dynamic MethodUsesImplicitDeclaration(dynamic reallyDictionary)
{
// this throws an exception, and the only difference is
// that the variable declaration is implicit
var dictionary = CastDictionary(reallyDictionary);
return dictionary.Get<int>("number");
}
static IDictionary<string, object> CastDictionary(dynamic arg)
{
return arg as IDictionary<string, object>;
}
}
static class Extensions
{
public static T Get<T>(this IDictionary<string, object> dictionary, string key)
{
var value = dictionary[key];
if (value is T)
return (T)value;
throw new InvalidOperationException();
}
}
The exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException was unhandled
HResult=-2146233088
Message='System.Collections.Generic.Dictionary<string,object>' does not contain a definition for 'Get'
Source=Anonymously Hosted DynamicMethods Assembly
StackTrace:
at CallSite.Target(Closure , CallSite , Object , String )
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at DynamicBug.Program.MethodUsesImplicitDeclaration(Object reallyDictionary) in c:\TFS\UnreleasedCode\POC\DynamicBug\DynamicBug\Program.cs:line 28
at DynamicBug.Program.Main(String[] args) in c:\TFS\UnreleasedCode\POC\DynamicBug\DynamicBug\Program.cs:line 16
InnerException:


varvariable declaration not behave like the type of the value you assign to it?Getdoes not exist.Getis an extension method. It seems like it applies just fine. If you change that line toreturn Extensions.Get<int>(dictionary, "number");then it executes as expected.