代码之家  ›  专栏  ›  技术社区  ›  John Kraft

为什么我遇到名称冲突

  •  2
  • John Kraft  · 技术社区  · 17 年前

    我们有一个我们使用的web服务框架;我没有参与创建它,也没有能力修改它,这本质上需要cookie-cuter代码向框架中添加一个“模块”。下面是代码格式的示例。

    Helper 每个班之间相隔几个月,我没有意识到我有两个班的名字是一样的。代码可以很好地编译,但部署到web服务器时会产生运行时错误。每当Processor_ProcessCompleted事件处理程序中的任何一个获得命中时,它都会抛出一个无效的强制转换异常,声明类型为 帮手 无法强制转换为类型 帮手

    帮手

    显然,我是不正确的,但我认为仅仅是宣布它们是私人的和内部的(不要与之混淆) internal

    
    namespace NameSpace1
    {
      public class Client1
      {
        Processor processor;
    
        private class Helper
        {
          public Property1 { get; set; }
          public Property2 { get; set; }
        }
    
        public Client1(Processor p)
        {
          processor = p;
          processor.ProcessCompleted += Processor_ProcessCompleted;
        }
    
        void Processor_Process(object sender, ProcessCompletedEventArgs e)
        {
          Helper helper = (Helper)e.UserState;
          // ... do a bunch of stuff
        }
      }
    }
    
    namespace NameSpace2
    {
      public class Client2
      {
        Processor processor;
    
        private class Helper
        {
          public Property1 { get; set; }    
        }
    
        public Client2(Processor p)
        {
          processor = p;
          processor.ProcessCompleted += Processor_ProcessCompleted;
        }
    
        void Processor_Process(object sender, ProcessCompletedEventArgs e)
        {
          Helper helper = (Helper)e.UserState;
          // ... do a bunch of stuff
        }
      }
    }
    

    关于Jon Skeet: 乔恩,谢谢你的回复。在这种情况下,所有客户端都使用相同的处理器。它们都将事件处理程序分配给事件。我理解您的意思,但是由于强制转换发生在特定方法的上下文中,因此它似乎应该能够从方法的上下文推断特定类型。

    object 到处理器。异步调用如下所示:

    
        processor.Process(request, helper);
    

    它发生在试图将其投射到响应的同一个类中。助手只包含一些简单的数据,服务使用这些数据来确定执行路径。

    编辑以解决Jon的编辑问题: 乔恩,我现在想我明白问题所在了。框架的设计者对其进行了专门设计,以允许所有客户端使用相同的处理器。因此,我认为您完全正确地描述了为所有订阅的客户端触发的事件。事实上,使用客户端的人正在编写如下代码:

    
    Processor processor = new Processor();
    Client1 client1 = new Client1(processor);
    Client2 client2 = new Client2(processor);
    
    client1.ExecuteSomeRequest(); // calls processor.Process(request, helper);
    client2.ExecuteSomeOtherRequest(); // calls processor.Process(request, helper);
    

    我感谢你的认真和全面的回答。

    1 回复  |  直到 17 年前
        1
  •  3
  •   Jon Skeet    17 年前

    不,仍然存在明显的冲突可能性,因为两个客户端最终都可以向同一个客户端添加事件处理程序 Processor ,至少使用您提供的代码。然后,两人都将尝试投球 e.UserState Helper 他们中只有一个是对的。 这意味着什么 UserState ,这意味着什么呢 设置为?你确定你从未通过同样的考试吗 Process Client ?

    编辑:响应您的编辑-如果所有客户端都使用相同的处理器,那么肯定会订阅相同的事件,这可能不是您想要的。

    至于UserState,您已经解释过它被称为 processor.Process(request, helper); 但是是谁打的电话,确切的电话类型是什么 helper ?

    犯罪嫌疑人 问题是因为您重用了相同的处理器对象,所以以前的客户机即使使用了新客户机,也仍然会触发其事件处理程序,但是如果没有完整的图片,就很难知道。

    如果你能制作一个简短但完整的程序来演示这个问题,那会有所帮助。

    推荐文章