Search code examples
c#c++inheritanceprivate-members

Adding private method to class by inheritance in C#


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"?


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).