为什么动态对象的赋值会抛出RuntimeBinderException ?
本文关键字:RuntimeBinderException 赋值 动态 对象 为什么 | 更新日期: 2023-09-27 18:13:45
为什么这段代码抛出一个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:更改异常处理程序以捕获所有异常,但没有影响
这一切都很正常。通过强制调试器在第一次出现异常时停止可以看到的内容。一个你可能已经不小心打开的选项。
- Newtonsoft.Json.Linq。jobobject '不包含'data'的定义
- Newtonsoft.Json.Linq。jobobject '没有包含'accountId'的定义
- 不能隐式转换Newtonsoft.Json.Linq类型。JValue' to 'string'。存在显式转换(您是否缺少强制类型转换?)
都是准确的。您看到DLR正在寻找可能的方法来找回属性。显而易见的方法都不起作用,在第二次尝试之后,它会尝试JObject实现的IDictionary<string, JToken>
接口。除了JToken值需要强制转换之外,几乎已经完成了。第四次尝试很好。
除了这些异常的成本之外,你没有真正的问题。这是严格限制的,您可以再次调用JsonConvert.DeserializeObject(),并注意现在不会得到异常。DLR已经记住了最优策略。