views:

63

answers:

2

Is there a way to override an abstract class's method signature which uses <T> with a ClassName so I can pass an object by reference without recasting it?

For example, I have a bunch of Object Managers. I want them all to contain a .Save(Object) method which will perform the appropriate save action based on the object state (Insert, Update, Delete, etc).

I was trying to create a base class which contains these methods:

protected virtual bool Update<T>(ref T _object) where T : ObjectBase
{
    throw new NotImplementedException();
}

public virtual bool Save<T>(ref T _object) where T : ObjectBase
{ 
    // Figure out which action to take based on _object's state and execute it
}

And I wanted my inherited classes to define the methods using something like this:

public override bool Update<Consumer>(ref Consumer _object)
{
    return _service.UpdateConsumer(ref _object);
}

My problem is that I can't specify that <T> will now be <Consumer>, and by keeping it at <T> I can't pass it by ref

+6  A: 

Instead of making the methods themselves generic, you should make the entire base class generic.

For example:

public abstract class ObjectManager<T> where T : ObjectBase {
    protected abstract bool Update(T obj);
}

Each concrete ObjectManager should inherit ObjectManager of the type that it manages, like this:

public class ConsumerManager : ObjectManager<Consumer> {
    protected override bool Update(Consumer obj) {
        ...
    }
}

Note, by the way, that your parameters should almost definitely not be passed ref.
You only need to ref keyword if you want to change the caller's variable to refer to a different instance.
For more information, see here.

SLaks
What do you mean? The two sets of code are in separate classes, with the derived classes inheriting from the base class. I just excluded the class definition because I was trying to simplify the code.
Rachel
Huh? What are you asking?
SLaks
Thank you, I wasn't aware I could do that.
Rachel
@Rachel He means that if you put `<T>` on the class, instead of the method, then all of your methods in the derived class will use the type you want. `public abstract void UpdateThing(T thing)` in the base class will become `public void UpdateThing(Consumer thing)` in the derived class.
Jay
A: 

You can add an overload that doesn't take a generic parameter.

public bool Update(ref Consumer _object){/*...*/}

If practical, however, I like SLaks's answer better. It affords making the method virtual or abstract.

P Daddy