我在 Silverlight 5 中有以下代码:
public void Send(Notification notification)
{
// Because the variable is passed as Notification, we have to trick the
// type-inference feature of the runtime so the message will be sent using
// the actual type of the object.
// Using the dynamic keyword, we can convert the type of the object passed
// to the Send method.
// This allows subscribers to register for messages using the generic interface.
dynamic stronglyTypedNotification = Convert.ChangeType(notification,
notification.GetType(),
CultureInfo.InvariantCulture);
SendCore(stronglyTypedNotification);
}
private void SendCore<T>(T notification)
where T : Notification
{
foreach (var handlerFactory in Handlers)
{
var handler = handlerFactory.Value as INotificationHandler<T>;
if (handler != null)
{
handler.Handle(notification);
}
}
}
我必须将此代码移植到 WPF 应用程序中运行。
当我在 WPF 应用程序中运行它并在 SendCore 方法中设置断点时,T 不是正确的类型。我只能假设这是因为泛型应该是静态定义的,因此编译器创建了它认为在运行时需要的 SendCore 版本。我猜 Silverlight 以不同的方式处理这个问题,因为这段代码在 SL 中完美运行。
此代码的目标是定位 Handlers 集合中包含的任何实现 INotificationHandler 的对象,其中 T 是传递给 Send 方法的对象的类型(继承基本 Notification 类),然后调用 Handle(T n) 方法那些物体。
如何在我的 WPF 应用程序中执行此操作?
更新
经过一些额外的测试,我发现了更奇特的结果。当我在 SendCore 方法的第一行设置断点并检查 T 和通知时,我发现:
- Intellisense 表示 T 是“GenericNotification”,它是程序集中的合法类。
- Intellisense 指示“通知”是正确的强类型类 (DataChangedNotification)。
- DataChangedNotification 不会以任何方式继承 GenericNotification。两个子类通知。
- 因为 T 正在解析为 GenericNotification,所以尝试将每个处理程序强制转换为 INotificationHandler<T> 将失败,因为没有实现 INotificationHandler<GenericNotification>
鉴于这个确切的代码在 Silverlight、一个控制台应用程序和另一个 WPF 应用程序(以及 David 在 LINQpad 中的测试)中工作,那么到底会发生什么?
我唯一能想到的就是代码实际上存在于 WPF 应用程序引用的类库中。不确定这是否重要,因为我在另一个(新)WPF 应用程序中测试了该场景并得到了正确的结果。