为什么我遇到名称冲突

时间:2009-03-16 19:25:24

标签: c# asp.net

我们有一个我们使用的Web服务框架;我没有参与创建,也没有能力修改,基本上需要cookie-cutter代码来为框架添加“模块”。代码格式的示例如下。

在下面的示例中,我将Helper类添加到几个月之后的每个类中,而没有意识到我有两个名为相同的类。代码编译很好,但是当部署到Web服务器时,它会产生运行时错误。无论何时无论是Processor_ProcessCompleted事件处理程序获得的点击,它抛出一个无效的转换异常,说明类型的对象Helper不能转换为类型Helper

我理解错误,并且通过重新分解Helper类来解决问题。这些辅助类从来没有自己的类以外的任何地方引用,他们是私有子类,它们在不同的命名空间,且无论是命名空间中,以任何方式,引用其他命名空间。我的问题是:为什么会发生这种碰撞?

显然,我是不正确的,但我想宣布他们的私人和内部的单纯行为(不要与混淆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
    }
  }
}

Re Jon Skeet: Jon,谢谢你的回复。在这种情况下,所有客户端都使用相同的处理器。他们都将事件处理程序分配给事件。我明白你在说什么,但由于投在具体方法的情况下发生,似乎它应该能够推断出从方法的上下文中的具体类型,就像

至于助手的助手,处理器本身实际上从来没有看到它填充到EventArgs中的内容。它只是处理器的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 个答案:

答案 0 :(得分:3)

不,仍然存在明显的冲突可能性 - 因为两个客户端最终都可以向同一个Processor添加事件处理程序,至少使用您提供的代码。然后两者都会尝试将e.UserState投射到Helper,其中只有一个是正确的。 设置UserState是什么意思,如何知道将Helper设置为哪种类型?您确定从未将同一Process传递给多个Client吗?

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

至于关于UserState的一点 - 您已经解释过它被称为processor.Process(request, helper);但是谁正在进行该调用,以及helper的确切类型是什么?

怀疑问题是由于您重复使用相同的处理器对象,因此以前的客户端仍然使用新客户端触发其事件处理程序,但是如果没有完整的图片则很难知道。

如果您可以制作一个简短但完整的程序来证明问题,那将会有所帮助。