处理dynamic时引发大量的Microsoft.CSharp.RuntimeBinderExceptions
我在C#中有一个标准的“dynamic词典”types的类 –
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 }
该应用程序做你所期望的,但debugging输出如下所示:
在Microsoft.CSharp.dll中发生第一次机会exception的typesMicrosoft.CSharp.RuntimeBinder.RuntimeBinderException 在Microsoft.CSharp.dll中发生第一次机会exception的typesMicrosoft.CSharp.RuntimeBinder.RuntimeBinderException 'ScratchConsoleApplication.vshost.exe'(托pipe(v4.0.30319)):加载“匿名托pipe的DynamicMethods程序集” 在Microsoft.CSharp.dll中发生第一次机会exception的typesMicrosoft.CSharp.RuntimeBinder.RuntimeBinderException 在Microsoft.CSharp.dll中发生第一次机会exception的typesMicrosoft.CSharp.RuntimeBinder.RuntimeBinderException
任何尝试访问dynamic成员似乎RuntimeBinderException
向debugging日志输出一个RuntimeBinderException
。 虽然我意识到一次机会的例外本身并不是一个问题,但这确实会给我带来一些问题:
-
我经常会将debugging器设置为“打破exception”,因为我正在编写WPF应用程序,否则所有exception最终都会转换为
DispatcherUnhandledException
,并且所有您想要的实际信息都将丢失。 WPF就是这样的。 -
只要我点击任何使用
dynamic
代码,debugging输出日志就变得毫无用处。 我所关心的所有有用的trace行都隐藏在所有无用的RuntimeBinderException
有没有什么办法可以关掉它,或者不幸的是, RuntimeBinder
就是这样构build的?
谢谢,猎户座
只要parsingdynamic对象上的属性,运行时就会尝试查找在编译时定义的属性。 来自DynamicObject doco:
您也可以将您自己的成员添加到从DynamicObject类派生的类中。 如果您的类定义了属性并覆盖了TrySetMember方法,那么dynamic语言运行库(DLR)首先使用语言联编程序来查找类中属性的静态定义。 如果没有这样的属性,则DLR调用TrySetMember方法。
如果运行时无法find一个静态定义的属性(例如100%静态types的世界中的编译器错误),则会引发RuntimeBinderException
。 从MSDN文章
RuntimeBinderException表示在通常的编译器错误意义上的绑定失败…
有趣的是,如果您使用ExpandoObject
,那么在尝试使用该属性时只会遇到一个exception:
dynamic bucket = new ExpandoObject(); bucket.SomeValue = 45; int value = bucket.SomeValue; //<-- Exception here
也许ExpandoObject
可以替代? 如果它不合适,你需要考虑实现IDynamicMetaObjectProvider
,这是ExpandoObject
如何dynamic分派的。 但是,它没有很好的logging,MSDN将您引用到DLR CodePlex以获取更多信息。
这也困扰着我。 我将exception添加到例外列表,以便我可以取消select它。 只需按照以下步骤操作
- 从debugging菜单中select例外。
- 点击右下angular的“添加…”button。
- 从Type下拉菜单中select“Common Language Runtime Exceptions”。
- 键入“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”作为名称。
- 点击OK。
- 现在,列表中将显示例外types。 只需取消select它。
我希望这个设置可以保存在不同的解决scheme中,但我不认为它可以,所以你将不得不在每个解决scheme上重新应用这个设置。