David
David

Reputation: 16067

Force child class to implement private method

I have the following code:

public abstract class NavEntityController<ChildEntity> where ChildEntity : NavObservableEntity
{
    public abstract void Delete(ChildEntity line);
    public abstract void Update(ChildEntity line);
    public abstract void Create(ChildEntity line);

    public void PushChangesToNav(NavObservableCollection<ChildEntity> lines) 
    {
        foreach (var line in lines)
        {
            line.ErrorLastAction = false;
            EntityState previousState = line.CurrentState;

            try
            {
                switch (line.CurrentState)
                {
                    case EntityState.Unchanged:
                        break;
                    case EntityState.NeedsCreate:
                        Create(line);
                        line.CurrentState = EntityState.Unchanged;
                        break;
                    case EntityState.NeedsUpdate:
                        Update(line);
                        line.CurrentState = EntityState.Unchanged;
                        break;
                    case EntityState.NeedsDelete:
                        Delete(line);
                        line.CurrentState = EntityState.Deleted;
                        break;
                }
            }
            catch (Exception e)
            {
                //...
            }        
        }
    }
}

I need a base class to inherit from this class, like such:

public class NavJobController : NavEntityController<NavObservableJob>
{
    public NavJobController( {}

    public override void Delete(NavObservableJob line) {//Implementation here}
    public override void Update(NavObservableJob line) {//Implementation here}
    public override void Create(NavObservableJob line) {//Implementation here}

    //Other functionality
}

However, I do not want someone to be able to do:

NavJobController j = new NavJobController();
j.Create(new NavObservableJob());

but only would like the following method:

j.PushToNav(); //and any other public functionality in the base class to be available

Essentially, I want to force the child class to implement CRUD operations, without exposing them to the public. The ideal syntax I was hoping for is the following:

private abstract void Delete(ChildEntity line);
private abstract void Update(ChildEntity line);
private abstract void Create(ChildEntity line);

Upvotes: 5

Views: 1842

Answers (2)

Mat&#237;as Fidemraizer
Mat&#237;as Fidemraizer

Reputation: 64943

This is why protected visibility exists (visible to both base class and derived classes, but not publicly available to use them from an instance).

If you need to publicly access these methods somewhere in your solution, you may need to use internal instead of protected and make internals visible to some assemblies using [InternalsVisibleTo] attribute.

Upvotes: 13

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391664

The way to do this is to use protected abstract. This exposes the methods to descendant types, but not to outsiders, as well as enforcing that some descendant has to implement the method.

So this is how you would declare it:

public abstract class NavEntityController<ChildEntity> where ChildEntity : NavObservableEntity
{
    protected abstract void Delete(ChildEntity line);
    protected abstract void Update(ChildEntity line);
    protected abstract void Create(ChildEntity line);

    ... rest of class

Upvotes: 1

Related Questions