首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析.NET 4 vs SL 5中的动态类型

解析.NET 4 vs SL 5中的动态类型
EN

Stack Overflow用户
提问于 2012-09-19 17:18:18
回答 2查看 124关注 0票数 1

我在Silverlight 5中使用了以下代码:

代码语言:javascript
复制
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中工作得很好。

此代码的目标是定位实现INotificationHandler的处理程序集合中包含的任何对象,其中T是传递给发送方法的对象的类型(子类为基本通知类),然后对这些对象调用句柄( on )方法。

如何在我的WPF应用程序中做到这一点?

更新

经过一些额外的测试后,我发现了更多奇怪的结果。当我在SendCore方法的第一行设置一个断点并检查T和通知时,我发现:

  • Intellisense表示T是"GenericNotification“,它是程序集中的合法类。
  • Intellisense表示"notification“是正确的强类型类(DataChangedNotification)。
  • DataChangedNotification不以任何方式子类GenericNotification。两个子类通知。
  • 由于T解析为GenericNotification,尝试将每个处理程序转换为INotificationHandler将失败,因为没有实现INotificationHandler。

考虑到这个精确的代码在Silverlight、控制台应用程序和另一个WPF应用程序(以及David在LINQpad中的测试)中工作,那么世界上会发生什么呢?

我唯一能想到的是,代码实际上存在于WPF应用程序引用的类库中。不确定这是否重要,因为我在另一个(新的) WPF应用程序中测试了该场景,并且得到了正确的结果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-20 07:20:06

这对我来说是可行的,这是预料之中的。如果不一样的话我会很惊讶的。

代码语言:javascript
复制
void Main()
{
    Send(new NA());
    Send(new NB());
}

public class Notification {}
public class NA : Notification {}
public class NB : Notification {}

public void Send(Notification notification)
{
    dynamic stronglyTypedNotification
        = Convert.ChangeType(notification,
                             notification.GetType(),
                             CultureInfo.InvariantCulture);

    SendCore(stronglyTypedNotification);
}

public void SendCore<T>(T notification) where T : Notification
{
    Console.WriteLine(typeof(T));
}

这输出

代码语言:javascript
复制
typeof (NA) 
typeof (NB)
票数 1
EN

Stack Overflow用户

发布于 2012-09-26 19:14:45

尽管存在明显的性格冲突,但我还是称赞丹尼尔促使我继续更深入地研究这个问题。我同时要求删除它,因为我认为它没有为其他任何人提供任何价值。

事实证明,这个问题确实起源于其他地方,并且被一个简单的ToString()重载所掩盖。

第一个问题:我看到的行为(和报告)是另一个开发人员帮助将ToString覆盖添加到基本Notification类中的结果,它在调试器中而不是数据类型中显示对象的名称。这就是为什么在VS中查看“notification”参数时显示了预期的类型名称。实际上,传入的对象类型是GenericNotification。

一旦我意识到这种情况正在发生,我就能够打开我们的框架代码(独立构建的独立解决方案)来查看对象在何处被实例化。在那里,我发现文件的.NET版本与Silverlight版本的实现不同。我们使用MEF进行依赖注入,而Silverlight版本的代码是根据导入的受支持类型列表解析数据类型。.NET版本使用了一个开关语句(ugh!)。

因此,我更改了.NET版本,以便使用MEF动态创建对象以帮助解析类型和中提琴!现在一切都如期而至,压力也得到了缓解(这是我们软件的关键功能,所以它不能工作……)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12499723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档