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