mardi 16 octobre 2018

Generic Base Class Overriding Non-Generic Base Class Function Pattern? (.NET)

I'm wondering if anyone has a good suggestion/pattern in mind for solving the following design issue. I have a heirarchy of command classes. At the most abstract level I have an ICommand interface. The result from executing an ICommand's RunCommand() function is an Object. Different commands will have different result types, so this is an appropriate abstraction.

Building the heirarchy out a bit more, it becomes desirable to use generics. I create a Generic.ICommand(Of TResult) interface.

There's some common boiler plate code like Run, TryRun, BeginRun, BeginTryRun, etc that I want for all commands - so I create a BaseCommand class that provides all this, and which implements the non-generic ICommand interface. The BaseCommand doesn't know how to actually execute anything however, so all of these commands ultimately invoke a protected abstract function called InternalRunCommand. This all works beautifully.

Now I want to create a generic version of that class: BaseCommand(Of T). It inherits from BaseCommand and also implements the generic ICommand(Of T) interface. This works, but now there is a discrepancy: The InternalRunCommand.

In the non-generic version InternalRunCommand returns an Object. In my generic BaseCommand(Of T) class I'd like to overload that with a generic version that returns the result as type T. Unfortunately, the VB.NET/C# compilers don't let you provide an overload of a method where the only difference is the return type.

Since this is a protected function, it ultimately doesn't make much difference to the overall API, but it nevertheless irritates me that I don't have an aesthetically pleasing solution to this bit of architecture.

For the time being I have overridden the non-generic InternalRunCommand to point to a new protected, abstract OnRunCommand function that takes the same parameters but returns a result of type T. The InternalRunCommand has also been declared NonOverridable. This maybe the closest I can get - but wanted to see if there are any better ideas out there? :)

Aucun commentaire:

Enregistrer un commentaire