我在这里遇到的事件是使用包含动态对象的参数触发的。它是在事件调用本身中直接创建的匿名对象,如
if(MyEvent != null) MyEvent(this, new SensoricDataEventArgs { Data = new { Action = "Start", Team = "Blau" } });
其中 SensoricDataEventArgs 的签名是这样的:
class SensoricDataEventArgs : EventArgs {
public dynamic Data { get; set; }
}
当我尝试在处理程序中访问该数据时(在相关的情况下位于另一个程序集中),我得到的只是 object 没有动作,即使我将Data属性重新转换为 dynamic 。甚至 dynamic 对象的DebuggerVisualizer也显示对象上有一个属性 Action 。
但是,我得到了上述例外。
这是我在事件处理程序中尝试做的图像,以及调试器中的信息。在图像中,调试器已在断点处停止。下一步抛出异常。
知道导致此异常的原因吗?我究竟做错了什么?
答案 0 :(得分:3)
问题是匿名类型被声明为internal
,因此您尝试访问的成员在您的其他程序集中不可见,并且DLR实际上在运行时对成员可访问性执行相同的编译时分析。它不会让您在运行时访问在编译时无法访问的内容。它看到匿名类型为internal
并抛出RuntimeBinderException
。
一种解决方案是显式编写反射代码而不是使用dynamic
。一个更易于维护的长期解决方案是从事件args中删除dynamic
,并更准确地定义组件之间的通信方式。
答案 1 :(得分:0)
另一种解决方案是使用 ExpandoObject 而不是匿名对象。
在我的特定情况下,考虑到时间不多(截止日期临近)这一事实,我将使用此解决方法,而不是重新考虑我的整个架构,并冒着已经完成的插件不兼容的风险。它工作,它保持兼容性。