为什么动态对象的赋值会抛出RuntimeBinderException?

时间:2015-09-21 20:14:19

标签: c#

为什么此代码会抛出RuntimeBinderException,如何解决此问题?为什么我不能在catch块中捕获这个异常?

如果我使用System.Web.Helpers.Json.Decode(response)来解析json字符串,也会发生同样的错误。

using Microsoft.CSharp.RuntimeBinder;
using Newtonsoft.Json;
using System;
using System.Windows;

namespace DynamicDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        try
        {
            String response = "{ \"data\":{ \"accountId\":\"YOUR_ACCOUNT_ID\"},\"message\":null}";
            dynamic obj = JsonConvert.DeserializeObject(response);
            String account = obj.data.accountId;
            Console.WriteLine(account);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

    }
}

}

输出......

'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero2\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero2.dll'. Symbols loaded.
'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0__b77a5c561934e089\System.Numerics.dll'. Symbols loaded.
'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Dynamic\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Dynamic.dll'. Symbols loaded.
Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll
'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'Anonymously Hosted DynamicMethods Assembly'. 
Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll   
Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll
YOUR_ACCOUNT_ID
'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 14.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CLIENTDIAGNOSTICS\XAMLDIAGNOSTICS\x86\WpfXamlDiagnosticsTap.dll'. Symbols loaded.
'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'C:\Windows\assembly\GAC\Microsoft.VisualStudio.OLE.Interop\7.1.40304.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.OLE.Interop.dll'. Module was built without symbols.
'DynamicDemo.vshost.exe' (CLR v4.0.30319: DynamicDemo.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll'. Symbols loaded.

更新1: 更改了异常处理程序以捕获所有异常但它没有区别

1 个答案:

答案 0 :(得分:5)

这一切都很正常。通过强制调试器停止在第一次机会异常时可以看到的东西。您可能已经意外启用的选项。

  • &#39; Newtonsoft.Json.Linq.JObject&#39;不包含&#39;数据&#39;
  • 的定义
  • &#39; Newtonsoft.Json.Linq.JObject&#39;不包含&#39; accountId&#39;
  • 的定义
  • 无法隐式转换类型&#39; Newtonsoft.Json.Linq.JValue&#39;到&#39;字符串&#39;。存在显式转换(您是否错过了演员?)

所有这些都是准确的。您正在看到DLR以可能的方式查找属性。在第二次尝试它尝试JObject实现的IDictionary<string, JToken>接口之后,没有明显的方法可行。除了JToken值需要演员之外,几乎没有。第四次尝试很好。

除了这些异常的代价之外,你没有真正的问题。严格限制,您可以再次调用JsonConvert.DeserializeObject()并注意您现在获取异常。 DLR记得最佳策略。

一切都按照应有的方式运作。