Question

I asked this question yesterday, but I think it was unclear what my primary concern was. In C++, we have private and multiple inheritance, which enables us to add private methods to classes by just inheriting from the class declaring these methods. That is, if there's a class

class B {
public:
    virtual void doMethodB();
};

and a class

class A : private B {
   virtual int doMethodA();
};

doMethodB() can be called from within doMethodA(), but is not accessible from outside.

Now, I'd like to mimic this behavior in C#. There is no multiple nor private inheritance. Up to know, I can think of four way to achieve somthing similar, but still with serious drawbacks:

First: Use an interface, i.e.

interface IB {
    public void doMethodB();
};
class A : IB {
    public void doMethodB();
    int doMethodA();
};

However, when we do this, doMethodB() is public, and must be implemented in each class inheriting from IB.

Second: Use a static method

public static class B {
    public static void doMethodB();
};

That way, there need only be one implementation, but the method is still public and can't be restricted to certain classes.

Third: Use a extension method, like that. That way however, the method is called on the object (i.e. a.doMethodB()) and not from "inside".

Fourth: Composition.

class A {
    private B b;
    public int doMethodA();
};

Now, B's methods can be called like b.doMethodB() from A only, but are other issues now regarding serialization, b == null etc.

Is there another alternative? And if not, which one among the presented ones would you consider "the best"?

Was it helpful?

Solution

Regarding your "First" proposal with interfaces: you can also implement the interface explicitly: "A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. " See / Source: http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx

However, i would choose the Composition approach. "Favor Composition over Inheritance", also see Prefer composition over inheritance?

Ideally, i would constructor-inject B into A by dependency injection, that should help mitigate your b == null concern.

Note: Using a static method / extension method (is a static method, too...) makes unit-testing A (respectively faking B) very hard, which is why i would forgo these solutions completely.

Edit: If you don't need B.doMethodB accessible from anyone else than A, you can also make B an abstract class and B.doMethodB a protected method. But i was thinking that you already know that ;-) (And because of the testing issues i would still favor composition over inheritance).

OTHER TIPS

I think the concept you are looking for is the protected access modifier. It means that only B itself and its derived classes can access the method, but others cannot.

class B {
    protected virtual void DoMethodB() {}
}

class A : B {
    virtual void DoMethodA() {
        DoMethodB();
    }
}

If you wanted, you can further restrict the access to protected internal which means that the method can only be accessed from derived classes inside your assembly.

Also, be aware of the consequences of virtual methods. If there is no explicit need to make a method virtual, it should not be marked virtual.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top