Search code examples
c#genericsinheritanceinterfaceabstract

How can I force a class that inherits from an abstract class to not use its base?


Please do not focus on the poor overall design I am dealing with a C#, EF-driven API where the original programmers programmed everything synchronously which caused extremely poor performance. I converted everything to async 1:1, which created some design pattern issues.

One of the problems is that all mapper classes inherited directly from an interface, something like:

Interface IConvertThings<T,S>()
{
   public Task<T> ConvertTo(S object);
   public Task<T> ConvertFrom(T object);
}

A problem we were facing already was that we had multiple duplication of code where one of these would not have a value (i.e. you could ConvertTo but not ConvertFrom or vice versa). To resolve this, I created an abstract class for all of the other objects involved to inherit from:

public abstract class AConvertThings<T,S> : IConvertThings<T,S>
{
  public Task<T> ConvertTo(S object) { throw new NotImplementedException(); }
  public Task<S> ConvertFrom(T object) { throw new NotImplementedException(); }
}

Conversion classes all now inherit from AConvertThings. The intent was that if a method wasn't defined in the conversion class (with "new" to hide the original), the AConvertThings method we be called and report the error and let the developer know they've called an incomplete method on that Converter (as some only are supposed to go one way).

The problem I'm experiencing is that even with the new keyword on the inheriting classes, the AConvertThings class is being called at runtime, throwing the error when the inheriting classes have a fully complete stack.

public async new Task<TYPE> ConvertTo(OTHERTYPE object) What am I overlooking?


Solution

  • If i understand you correctly, you want to override the ConvertTo and ConvertFrom methods in derived classes that support converting to/from.

    Using the new keyword is not overriding any methods, it's just making hiding (shadowing) them explicit. See here for an explanation of the differences in behavior between member overriding and hiding: Overloading,Overriding and Hiding?

    To make ConvertTo and ConvertFrom overridable, use the virtual keyword on the methods in the AConvertThings base class. Any deriving class that then wishes to override one or both of these methods would then use the override keyword. (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/virtual)