我在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.dll A 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.dll A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
任何尝试访问动态成员似乎都会向调试日志输出RuntimeBinderException
。虽然我知道第一次机会异常本身并不是问题,但这确实给我带来了一些问题:
我经常将调试器设置为“中断异常”,因为我正在编写WPF应用程序,否则所有异常最终都会转换为DispatcherUnhandledException
,以及您想要的所有实际信息迷路了。 WPF很糟糕。
只要我点击任何使用dynamic
的代码,调试输出日志就会变得毫无用处。我关心的所有有用的跟踪线都隐藏在所有无用的RuntimeBinderException
s
有什么办法可以解决这个问题,或者遗憾的是RuntimeBinder
是不是就这样建了?
谢谢,猎户座
答案 0 :(得分:25)
每当解析动态对象上的属性时,运行时都会尝试查找在编译时定义的属性。来自DynamicObject doco:
只要运行时找不到静态定义的属性(即100%静态类型世界中的编译器错误),就会抛出您也可以添加自己的会员 从DynamicObject派生的类 类。如果你的班级定义 属性,也覆盖了 TrySetMember方法,动态 语言运行时(DLR)首先使用 语言绑定器寻找静态 类中属性的定义。 如果没有这样的财产,DLR 调用TrySetMember方法。
RuntimeBinderException
。来自MSDN article
... RuntimeBinderException表示一个 在一个意义上没有约束力 通常的编译错误......
有趣的是,如果您使用ExpandoObject
,则在尝试使用该属性时只会遇到一个例外:
dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here
也许ExpandoObject
可能是替代方案?如果它不合适,您需要考虑实施IDynamicMetaObjectProvider
,这是ExpandoObject
动态调度的方式。但是,它没有很好的文档记录,MSDN会将您引用到DLR CodePlex以获取更多信息。
答案 1 :(得分:21)
这也困扰着我。我将异常添加到例外列表中,以便我可以取消选择它。只需按照以下步骤操作:
我希望此设置可以在解决方案中保存,但我认为不可以,因此您必须在每个解决方案上重新应用此设置。