Tech Off Thread

4 posts

Generic Base class problem

Back to Forum: Tech Off
  • User profile image
    JoshB

    I'm wondering if anyone has some insight to this problem.

    I'm working with a business object base class that uses generics to return strongly typed data for some of the static methods.

    public class BusinessObjectBase<T>
    {
          public static IList<T> GetAList()
          {
                IList<T> listOfBusinessObjects = new List<T>();
                // code to populate the list.
                return listOfBusinessObjects
          }
    }

    The business object base class of course does a lot more but this is a good example why I decided to use generics.

    I have a deriving class Customer:

    public class Customer : BusinessObjectBase<Customer>
    {
    }

    First this seems overly redundant specifying the type for the business base right after the declaration of the Customer type, but it sure beats passing the Customer type to every generic static method. Probably look something like this.

    IList<Customer> customers = Customer.GetAList<Customer>();

    So adding the generic to the base class made sense. This looks a lot cleaner:

    IList<Customer> customers = Customer.GetAList();

    I ran into this problem however. I wanted to add a bunch of specific things to the Customer class, but since I have other applications that use the Customer class, I decided to derive from it.

    public class SpecialCustomer: Customer
    {
    }

    This worked great until I wanted to call the static methods on the base class.

    IList<SpecialCustomer> specialCustomers = SpecialCustomer.GetAList();

    The compiler notified me that SpecialCustomer.GetAList() actually returned IList<Customer>. WHAT! Yep, SpecialCustomer implements Customer which implements BusinessObjectBase<Customer>. This was apparently obvious to everyone but me.

    So Is there anyway to resolve this. I certainly cant add a generic to Customer.

    public class Customer<T> : BusinessObjectBase <T>
    {
    }

    It'd work for SpecialCustomer:

    public class SpecialCustomer: Customer<SpecialCustomer> {}

    But just cause you can do it, doesn't mean it's to be done. That would look sweet defining a regular customer.

    Customer customer = new Customer<Customer<Customer< Customer<Customer<Customer<Customer<Customer< Customer<Customer<Customer... Ugh...

    Being a noob sux Perplexed

  • User profile image
    ilya

    Hey JoshB,

    Generics are awsome, but they can cause you some grief if you don't watch out.

    One way you can take care of this problem is to hide the implementation of your Customer class that returns the IList<Customer> and simply create a new IList<SpecialCustomer> and basically create instances of SpecialCustomer from the Customer objects that you would get from base.

    Hope that helps.

  • User profile image
    cdwatkins

    Your talking about a contra/co- variance problem.  The problem is that IList<Bob> isnt assignable to IList<Person> even though Bob is a type of person.  They fixed this problem in .NET 4.

  • User profile image
    ploe

    cdwatkins said:

    Your talking about a contra/co- variance problem.  The problem is that IList<Bob> isnt assignable to IList<Person> even though Bob is a type of person.  They fixed this problem in .NET 4.

    Probably not the solution you are looking for, but you could do this:

     

    Have only one Customer class and make your 'special' members internal so only you can use them. If it's in a different assembly from where you need it you can use this to gain access to the internal members: http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.