使用泛型的新手多态性问题

时间:2010-02-23 10:25:41

标签: c# generics oop polymorphism

我有以下方法接受详细信息对象,验证它,将其转换为请求并将其排入队列。除了我遇到麻烦的验证请求之外,一切都很好。基本上,每个不同的细节对象都有不同的验证逻辑。我从通用约束中知道,细节对象必须具有BaseDetails的基类,并且从实际的泛型参数我知道确切的派生类型,但不知道如何使用它们来编写我的验证器类,以便它处理所有类型的细节:

private void Enqueue<TDetails, TRequest>(TDetails details)  
   where TDetails: BaseDetails where TRequest: BaseRequest
{
  bool isValid = _validator.Validate(details);

  if (isValid)
  {
    TRequest request = ObjectMapper
      .CreateMappedMessage<TDetails, TRequest>(details);

    _queue.Enqueue(request);
  }
}

4 个答案:

答案 0 :(得分:2)

这只意味着必须有相应的验证器层次结构,每个验证器都附加到自己的TDetails对象。由于TDetails始终为BaseDetails,因此您需要手动指定您支持的子类并将链执行链接到嵌套的验证器。

答案 1 :(得分:1)

对我而言,似乎验证逻辑应该附加到细节对象本身(如果可能的话,当然)。然后,您可以标记基类抽象,并在必要时覆盖特定详细信息类的Validate方法。

另一方面 - “继承的构图”现在很流行。

答案 2 :(得分:1)

  

我从泛型约束中知道,details对象必须具有BaseDetails的基类

这在编译为字节代码的过程中是已知的(我的意思是Visual Studio知道它)

  

从实际的通用参数我知道确切的派生类型

但只有在JIT编译之后才知道(Visual Studio对此一无所知)。这就像晚期绑定。

因此,如果你想用一些具有不同参数类型的方法编写一个验证器类,则不能这样做,因为Visual Studio编译器不知道(在编译时)将调用哪个方法。

我认为没有办法跳过编写'switch(typeof(TDetails))'逻辑,其中验证者必须由TDetails选择。所以你必须写一些工厂,就像Sam Holder上面写的那样。

PS:对不起我的英文。我正在使用stackoverflow来学习英语写作:)

答案 3 :(得分:0)

我认为你需要为TDetails的每个实现创建一个验证器类,它知道如何验证特定的实现,然后有一个工厂为给定的TDetails实现生成正确的验证器并让你的_validator获取正确的类来执行来自工厂的工作,并让班级进行验证。

显然,你可以在基类中进行一些常见的验证。

您可能最好对对象本身进行验证,而不是为每个TDetails实现创建单独的验证器......