我有以下方法接受详细信息对象,验证它,将其转换为请求并将其排入队列。除了我遇到麻烦的验证请求之外,一切都很好。基本上,每个不同的细节对象都有不同的验证逻辑。我从通用约束中知道,细节对象必须具有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);
}
}
答案 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实现创建单独的验证器......