Newbie polymorphism question using generics
I have the following method that takes in a details object, validates it, converts it to a request and enqueues it. Everything is fine apart from the validate request which I am having trouble with. Basically, there is different validation logic for each different details object. I know from the generic constraint that the details object must have a base class of BaseDetails and from the actual generic parameter I know the exact derived type, but do not know how to use these to write my validator class so it handles all types of details:
private void Enqueue<TDetails, TRequest>(TDetails details)
where TDetails: BaseDetails where TRequest: BaseRequest
{
bool isValid = _validator.Validate(details);
i开发者_Python百科f (isValid)
{
TRequest request = ObjectMapper
.CreateMappedMessage<TDetails, TRequest>(details);
_queue.Enqueue(request);
}
}
It just means that there must be a corresponding hierarchy of validators, each attached to its own TDetails
object. Since TDetails
is always BaseDetails
, you need to manually specify which child class you support and chain execution to a nested validator.
For me it seems that validation logic should be attached to details objects themselves (if possible, of course). Then you could mark base class abstract and override Validate
method for specific details classes if necessary.
On the other hand - 'composition over inheritance' is trendy at the moment.
I know from the generic constraint that the details object must have a base class of BaseDetails
This is known in process of compilation to byte code (i mean Visual Studio knows it)
and from the actual generic parameter I know the exact derived type
But this is known only after JIT compilation (Visual Studio doesn't know anything about it). It's like late binding.
So if you want to write one validator class with several methods with different argument types, you can't do this, because Visual Studio compiler didn't know (in compile time) wich method will be called.
I believe that there are no ways to skip writing 'switch(typeof(TDetails))' logic, where validator must be selected by TDetails. So you must write some kind of factory, like Sam Holder wrote above.
PS: Sorry for my english. I'm using stackoverflow also for study english writing :)
I think you need to create a validator class for each implementation of TDetails which knows how to validate that particular implementation, then have a factory to produce the right validator for a given TDetails implementation and have your _validator get the correct class for doing the work from the factory and get the class to do the validation.
Obviously you could have some of the common validation in a base class.
You might be better having the validation on the object itself though rather than create a separate validator for each TDetails implementation...
精彩评论