Abstract Generic Base Classes... how to refer to the derived type?

Hello all, my first time posting here on MSDN, so be easy on me. :)

I have an abstract base class that takes a generic type parameter to strongly type a member. So, I have something like:

public abstract class BusinessObjectBase<INFO> : IBusinessObject
where INFO : EntityBase
{
public IBusinessObject Update()
{ ... }
}

...

public sealed class User : BusinessObjectBase<UserEntity>
{
...
}


My issue is, I'd like to have a method pass back a saved version of the business object back from the Update() method; however, there doesn't seem a way to do this in a strongly-typed way. From the User, object, I can only pass back either a type "object", type "IBusinessObject", or type "BusinessObjectBase<INFO>". I'd like to just pass back a type User, but there doesn't appear a way to refer to the final derived type from the generic abstract base class. I kind of expected a THISTYPE or some kind of keyword I could use in place of a generic type parameter in the generic abstract base class. I'm not that in tune with the inner workings of the CLR, so I realize that may not be possible, but my question is:

1. Is it possible to do this

2. If not, why

Thank you!

-Sean McElroy


Answer this question

Abstract Generic Base Classes... how to refer to the derived type?

  • Anand Raman - MSFT

    Hi, Sean

    I'm afraid it all about designing mode, if you design the BusinessObjectBase as abstract class, it should behave like an abstract one.

    Otherwise, drop the "abstract".

    Thanks.



  • WilliamW6488

    Hrm, you are correct, thinking about it more now, this is a limitation present in any abstract base class, not just generic ones... thanks for pointing that out. Just FYI I am using an explicit type parameter right now since I'm unable to work around the problem, I just don't like this so much because it seems to make the interface to consumers unnecessarily kludgy by requiring that explicit type parameter to provide information the compiler should be able to figure out, for instance, I have to call my update method like:

    User savedUser = currentUser.Update<User>();

    It seems feasible the language could be enhanced to provide something in the abstract base class method definition like:

    public THISTYPE Update()
    { ... }

    That's okay, I understand I can't have my cake with the current C# language design. My only question now is more of a theoretical one: what are the technical limitations that would prevent such a feature from being added to the language in the future

    -Sean

  • mblas

    public abstract class BusinessObjectBase<INFO> : IBusinessObject
    where INFO : EntityBase
    {
    public INFO Update() { ... }
    }

    or


    public sealed class User : BusinessObjectBase<UserEntity>
    {
    public BusinessObjectBase<UserEntity> Update(){ ... }

    }

    this will return the right type...

    you can use your generic constraint for members, properties, method parameters, return values etc :)

    Hope this helps you out, please close the thread if it does



  • vbMarkO

    Good morning,

    Actually my intention is for the update method to pass back a return type of the object itself (i.e. User in this example), not the contained EntityBase-extended one (UserEntity as you provided in your example). Also, the reason I'm inquiring about a missing "THISTYPE" kind of feature is it'd be really nice not to have to implement methods in each class that extends BusinessObjectBase<INFO> just to cast things to their proper type. Without that feature I can't really ensure derived types would implement such methods in a uniform way. The example you posted above couldn't work for me because the derived type's update method would collide with the base class implementation since they only vary by return type.

    Hope that makes sense. :)

  • Bob Lyden

    What I would do, is have the method return an object of type BusinessObjectBase<INFO>, like it's doing right now, and let them cast it. The user can always cast it to the appropriate type. This looks less ugly than what you did (if I understood well, you added a second generic parameter).

    Here's an idea:

    public abstract class BusinessObjectBase<INFO> : IBusinessObject
    where INFO : EntityBase
    {
    public
    BusinessObjectBase<INFO> Update()
    { ... }
    }

    public sealed class User : BusinessObjectBase<UserEntity>
    {
    public UserEntity Update()
    {
    return (UserEntity) base.Update()
    }

    }

    Is this what you were looking for


    An additional note:
    By looking at your code, maybe the return type actually is INFO. Am I wrong


  • Avhacker

    It's not possible without an extra explicit type parameter. This isn't specific to generics, you have the same issue with non-generic base classes.



  • Abstract Generic Base Classes... how to refer to the derived type?