2013-04-21 43 views
1

我在这里得到了一个事件,其中包含一个包含动态对象的参数。这是在事件调用自身直接创建一个匿名对象,像没有定义“动作”动态?

if(MyEvent != null) MyEvent(this, new SensoricDataEventArgs { Data = new { Action = "Start", Team = "Blau" } }); 

其中SensoricDataEventArgs的签名是这样的:

class SensoricDataEventArgs : EventArgs { 
    public dynamic Data { get; set; } 
} 

当我试图访问一个处理程序数据(这是在另一个程序集,以防万一),我得到的是一个例外,对象没有定义动作,即使我重新强制Data属性为动态ic。对于动态对象甚至DebuggerVisualizer对象显示对象上有一个属性动作

但是,我得到了上述例外。

下面是我正在尝试在事件处理程序中执行的图像,它们都与调试器的信息一起。在图像中,调试器停在断点上。下一步引发异常。

任何有关导致此异常的想法?我究竟做错了什么? MyEvent handler

+0

尽量避免动态 您可以使用Dictionary而不是Data,其中包含Action作为键和“Start”作为Value。如果这不是必须的,你最好做类似的事情,创建一个枚举动作,包括开始,运行,停止,... – 2013-04-21 09:09:52

+0

动态是强制性的,因为可能触发此事件的“事物”的体系结构。有一个插件系统,我自己实施,建立在它上面。嗯,并补充说,我在其他地方使用托管的IronPython/DLR,这些地方也是基于动态的。 – 2013-04-21 09:14:35

+0

我与@thefiloe就此。看起来你想要一个“可以做任何事情”的对象,这总是有点模糊,有点迹象表明某种东西没有被正确地思考。如果这些东西可以包含各种不同的数据,那么你应该看看它是如何实现的。鉴于你说你自己实现了这个插件系统,我不能购买“这是强制性的”推理:) – 2013-04-21 09:16:55

回答

3

的问题是,匿名类型声明internal,所以你要访问的成员是不可见的其他组件和DLR实际执行上,在运行时成员可访问相同的编译时分析。它不会让你在运行时访问在编译时无法访问的东西。它看到匿名类型是internal并且抛出RuntimeBinderException

一个解决方案是显式编写反射代码,而不是使用dynamic。更可维护的长期解决方案是从事件参数中删除dynamic,并更精确地定义组件之间的通信方式。

+0

该死!对不起......呃,好吧......看起来我真的不得不重新考虑我的建筑......无论如何感谢。 – 2013-04-21 09:44:53

0

另一种解决方法是使用ExpandoObject而不是匿名对象。

在我的特殊情况下,考虑到时间不足(截止日期逼近),我将使用此解决方法,而不是重新考虑整个体系结构,并冒着已完成插件的不兼容性的风险。它工作并保持兼容性。

+0

或者你可以使用普通的命名类型。这不应该要求你改变架构,因为它可以与'dynamic'一起工作。 – svick 2013-04-21 12:27:24

+0

也许吧。这就要求插件的开发人员也要使用正常的类型。可能是可以接受的,但对他们来说不太舒服,因为他们将不得不编写更多的代码。也许我会在截止日期之后再考虑一次,因为还有更多时间来改善这些架构缺陷。 – 2013-04-21 13:37:25