我在 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
}
应用程序执行您期望的操作,但调试输出如下所示:
Microsoft.CSharp.dll 中发生了“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的第一次机会异常 Microsoft.CSharp.dll 中发生了“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的第一次机会异常 “ScratchConsoleApplication.vshost.exe”(托管 (v4.0.30319)):已加载“匿名托管 DynamicMethods 程序集” Microsoft.CSharp.dll 中发生了“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的第一次机会异常 Microsoft.CSharp.dll 中发生了“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的第一次机会异常
任何尝试访问动态成员似乎都会向调试日志输出
RuntimeBinderException
。虽然我知道第一次机会异常本身并不是问题,但这确实给我带来了一些问题:
我经常将调试器设置为“异常时中断”,因为我正在编写 WPF 应用程序,否则所有异常最终都会转换为
DispatcherUnhandledException
,并且您想要的所有实际信息都会丢失。 WPF 就这么烂。一旦我点击任何使用
dynamic
的代码,调试输出日志就变得毫无用处。我关心的所有有用的跟踪线都隐藏在所有无用的RuntimeBinderException
s有什么办法可以关掉这个功能吗,或者不幸的是
RuntimeBinder
就是这样构建的?
谢谢,猎户座
每当解析动态对象上的属性时,运行时都会尝试查找在编译时定义的属性。来自 DynamicObject doco:
每当运行时找不到静态定义的属性时,就会抛出您还可以添加自己的会员 从 DynamicObject 派生的类 班级。如果你的类定义了 属性,并且还覆盖 TrySetMember方法,动态 语言运行时 (DLR) 首先使用 语言绑定器寻找静态 类中属性的定义。 如果没有此类财产,DLR 调用 TrySetMember 方法。
RuntimeBinderException
(即在 100% 静态类型的世界中会出现编译器错误)。来自MSDN文章
...RuntimeBinderException 代表一个 未能在某种意义上绑定 常见的编译器错误...
ExpandoObject
,则在尝试使用该属性时只会遇到一个异常:
dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here
也许
ExpandoObject
可以是替代方案?如果它不合适,您需要考虑实现 IDynamicMetaObjectProvider
,这就是 ExpandoObject
进行动态调度的方式。但是,它没有很好的记录,MSDN 建议您参阅 DLR CodePlex 以获取更多信息。
这也困扰着我。 我将该例外添加到例外列表中,以便我可以取消选择它。 只需按照以下步骤操作:
我希望此设置可以跨解决方案保存,但我认为不能,因此您必须在每个解决方案上重新应用此设置。
错误
'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
当 Csharp 尝试渲染未定义的模型对象时,会在前端发生。你有两个选择。定义对象或将其从前端删除。我确信删除是防止此错误的更好选择,因为您无论如何都不会使用它,因为它未定义。这是一个例子;
后端
public SomeModel Index(){
var model = new SomeModel{
FirsName = "John"
}
return View(model)
}
前端
@model appname.Models.SomeModel
<div>@Model.FirstName</div> //This wouldn't throw an error
<div>@Model.LastName</div> //This would throw an error