我遇到过在C#中使用动态变量的问题.这是在编写NancyFx路由模块时出现的,但我已将问题归结为下面的示例.虽然我在原始代码中收到了一个不同的例外,但示例代码仍然会抛出一个我认为是错误的异常.有没有人看到这里发生了什么,或有其他人遇到类似的问题?
请注意,以下帖子可能是相关的: StackOverflowException通过动态访问泛型类型的成员时:.NET/C#framework bug? System.Dynamic错误?
代码:
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();
    }
}
例外: 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:
问题是,当您没有将对象明确分配给IDictionary<string,object>声明时,该对象仍将是动态类型(请参阅图像中的类型分辨率).
正如Eric Lippert在/sf/answers/371920461/中指出的那样,对于动态类型,呼叫站点将无法使用扩展方法:
为了扩展Jon的答案,这不起作用的原因是因为在常规的非动态代码扩展方法中,通过对编译器已知的所有类的完整搜索来工作,该静态类具有匹配的扩展方法.搜索按顺序进行,基于命名空间嵌套和每个命名空间中可用的"using"指令.
这意味着为了正确解析动态扩展方法调用,DLR必须在运行时知道所有命名空间嵌套和"using"指令都在源代码中.我们没有将所有信息编码到呼叫站点中的机制.我们考虑发明这样一种机制,但认为它的成本太高,并且产生太多的进度风险值得.
我将您的代码加载到测试方法中,以显示var dictionary在运行时与实际声明相比实际解决的内容.
明确声明:
 

隐含声明
 

如果你看一下dictionary显式声明的类型解析有类型System.Collection.Generic.IDictionary而隐式声明有类型dynamic{System.Collections.Generic.Dictionary}
| 归档时间: | 
 | 
| 查看次数: | 2283 次 | 
| 最近记录: |