RenniePet
RenniePet

Reputation: 11658

Is it possible to (partially) implement an abstract method and still require derived classes to also implement it?

Here's a prototype of what I'd like to do, except that I realize that it can't work the way I've written it:

using System.Collections.ObjectModel;

namespace Merlinia.CommonClasses
{
   public abstract class JustTesting<TItem> : KeyedCollection<string, TItem>
   {
      protected override string GetKeyForItem(TItem anItem)
      {
         return GetKeyForItem(anItem).ToUpperInvariant();
      }

      protected new abstract string GetKeyForItem(TItem anItem);
   }
}

Now I do realize that by changing the name of the abstract method I require in the derived classes that it does work:

using System.Collections.ObjectModel;

namespace Merlinia.CommonClasses
{
   public abstract class JustTesting<TItem> : KeyedCollection<string, TItem>
   {
      protected override string GetKeyForItem(TItem anItem)
      {
         return NewGetKeyForItem(anItem).ToUpperInvariant();
      }

      protected abstract string NewGetKeyForItem(TItem anItem);
   }
}

It's just that I'd prefer that the method name was the same, GetKeyForItem, in all of the classes. Is there any way to make that work?

Upvotes: 1

Views: 1173

Answers (1)

user743382
user743382

Reputation:

You can insert an extra class and an internal helper function in the hierarchy to do this.

using System.Collections.ObjectModel;

namespace Merlinia.CommonClasses
{
   public abstract class JustTestingBase<TItem> : KeyedCollection<string, TItem>
   {
      internal JustTestingBase()
      {
        // so that other assemblies cannot misuse this as their own base class
      }

      protected sealed override string GetKeyForItem(TItem anItem)
      {
         return GetKeyForItemHelper(anItem).ToUpperInvariant();
      }

      internal abstract string GetKeyForItemHelper(TItem anItem);
   }

   public abstract class JustTesting<TItem> : JustTestingBase<TItem>
   {
      protected new abstract string GetKeyForItem(TItem anItem);

      internal override string GetKeyForItemHelper(TItem anItem)
      {
        return GetKeyForItem(anItem);
      }
   }
}

Upvotes: 2

Related Questions