Michael Kaldwid Michael Kaldwid - 3 months ago 12
C# Question

Is there an alternative to using a NotImplementedException when a subclass doesn't use a function in an abstract class?

I'm making a simple web form to gather customer data and enter it into a database. I have 5 sub-classes:

Customer
,
Bank
,
Employee
,
Owner
, and
TradeReference
which inherit from the abstract class,
DataEntry
.
DataEntry
has a function
public void InsertSelfIntoDataBase(int id);
. The id parameter is the primary key from the Customers Table (Bank, Employee, Owner and TradeReference have a many-to-one relationship with Customer), so a
Customer
doesn't need an id to be inserted (CustomerID is auto Incremented in the database).

Currently, my code is set up so that
Bank
,
Employee
,
Owner
, and
TradeReference
implements the
InsertSelfIntoDataBase
function in the parent class, while
Customer
throws a NotImplementedException, so the code for the
Customer
class code looks a little like this:

public int InsertSelfIntoDataBase()
{
int customerID = InsertCustomerAndReturnScalor();
return customerID;
}


public override void insertSelfIntoDataBase(int id)
{ throw new NotImplementedException("Customer does not use this function"); }


This implementation works, but it bugs me that I have to use a NotImplementedException; Like I can't shake the feeling that my professors form college somehow know and are silently judging me. Is there a better way of doing this?

Answer

This sort of situation can indicate a less than ideal abstract class model. Perhaps you could implement abstract class DataEntry without the insertSelfIntoDataBase(int) method, and then derive a second abstract class such as SelfInsertingDataEntry : DataEntry that defines the abstract method insertSelfIntoDataBase(int) so that concrete classes can inherit from either one depending on whether or not they implement the method.

With this trick, polymorphism related to other methods would be preserved since any concrete instance (whether or not it implemented insertSelfIntoDataBase) could be cast to type DataEntry.

@Recursive also had a good point in a comment, suggesting moving the insertSelfIntoDataBase method into an interface. You could then keep your DataEntry class hierarchy strictly related to Entry type taxonomy and allow some, none, or all descendants to implement or not implement the interface as they wish without requiring them to switch their parent.

Comments