gpt4 book ai didi

c# - 处理动态时抛出很多第一次机会 Microsoft.CSharp.RuntimeBinderExceptions

转载 作者:IT王子 更新时间:2023-10-29 03:49:33 26 4
gpt4 key购买 nike

我在 C# 中有一个标准的“动态字典”类型类 -

class Bucket : DynamicObject
{
readonly Dictionary<string, object> m_dict = new Dictionary<string, object>();

public override bool TrySetMember(SetMemberBinder binder, object value)
{
m_dict[binder.Name] = value;
return true;
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return m_dict.TryGetValue(binder.Name, out result);
}
}

现在我这样调用它,如下:

static void Main(string[] args)
{
dynamic d = new Bucket();
d.Name = "Orion"; // 2 RuntimeBinderExceptions
Console.WriteLine(d.Name); // 2 RuntimeBinderExceptions
}

该应用会按照您的预期进行操作,但调试输出如下所示:

A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dllA first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll'ScratchConsoleApplication.vshost.exe' (Managed (v4.0.30319)): Loaded 'Anonymously Hosted DynamicMethods Assembly'A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dllA first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll

任何 访问动态成员的尝试似乎都会向调试日志输出 RuntimeBinderException。虽然我知道第一次机会异常本身并不是问题,但这确实给我带来了一些问题:

  1. 我经常将调试器设置为“异常中断”,因为我正在编写 WPF 应用程序,否则所有异常最终都会转换为 DispatcherUnhandledException,所有实际你想要的信息丢失了。 WPF 就是这么烂。

  2. 只要我点击任何使用 dynamic 的代码,调试输出日志就会变得毫无用处。我关心的所有有用的跟踪行都隐藏在所有无用的 RuntimeBinderException

有什么方法可以关闭它,或者不幸的是 RuntimeBinder 就是这样构建的?

谢谢,猎户座

最佳答案

每当解析动态对象的属性时,运行时都会尝试查找在编译时定义的属性。来自 DynamicObject doco:

You can also add your own members to classes derived from the DynamicObject class. If your class defines properties and also overrides the TrySetMember method, the dynamic language runtime (DLR) first uses the language binder to look for a static definition of a property in the class. If there is no such property, the DLR calls the TrySetMember method.

RuntimeBinderException 在运行时找不到静态定义的属性时抛出(即在 100% 静态类型的世界中会出现编译器错误)。来自 MSDN article

...RuntimeBinderException represents a failure to bind in the sense of a usual compiler error...

有趣的是,如果你使用 ExpandoObject ,您在尝试使用该属性时只会遇到一个异常:

dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here

也许 ExpandoObject 可以作为替代方案?如果不合适,您需要考虑实现 IDynamicMetaObjectProvider ,这就是 ExpandoObject 进行动态调度的方式。但是,它没有很好的文档记录,MSDN 推荐您访问 DLR CodePlex 以获取更多信息。

关于c# - 处理动态时抛出很多第一次机会 Microsoft.CSharp.RuntimeBinderExceptions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2954531/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com