Reputation: 777
Let's say I have two objects, Master
and Slave
.
Slave
has a method named Init();
. The thing about Init()
is, that I need it to be virtual, because it contains user's initialization code, but I also need it to get called automatically when the Slave
is added to Master
's List. But the method must not be callable by the user, it has to be automatic.
The first thing that I tried is an event - create an event SlaveInitialized
that a Slave
object could handle in its OnSlaveInitialized
handler. This wouldn't work though, because there's a lot of Slave
objects and I have no control over the order in which they get created and need to be initialized.
The second thing that I tried is internal method - internal Init()
would be called when the object is added to Master
's list and all seems okay, until I realized that by doing so I cannot inherit the method in a public class.
So the third thing I did and that worked is this - I created an internal method called _Init()
that simply calls a protected virtual Init()
, which solved my problem.
Now I want to ask - do I just have a major strike of being stupid, because I am missing the painfully obvious solution here, or is this the way it's normally done? What is the proper way? I hope I got the point of what I'm asking across, I tried my best to explain the problem.
Thanks for any help
This is the gist of the code I now have. Its point is to have Init() invisibly and automatically called when you add any Slave object to the Master's list via Master.AddSlave();
public class Master
{
private List<Slave> _slaves;
public void AddSlave(Slave slave)
{
// Call the "hidden" init
slave._Init();
_slaves.Add(slave);
}
}
public class Slave
{
internal void _Init()
{
// Call the topmost overloaded method.
Init();
}
protected virtual void Init()
{
}
}
public class SuperSlave : Slave
{
protected override void Init()
{
// Now this method gets called automatically
// when Master.AddSlave adds this object.
}
}
Upvotes: 0
Views: 194
Reputation: 25763
While this doesn't answer the question the way you might want it, however I feel this could be an approperiate solution.
I would recommend throwing an InvalidOperationException if the Init
method gets called multiple times.
Description: The exception that is thrown when a method call is invalid for the object's current state.
In my opinion it should not be your responsibility to police your objects from being abused, so long as documentation is written properly, your objects properties and method names describe what they do, it should be enough for most users (developers) consuming your code to understand how it works.
For those who decide to call Init
themselves and then add to the Master
object, you can throw that exception so they will know that their method for using the class is incorrect.
EDIT:
Naming the method OnInit
might be a good idea, that way the user of the class has an indication that it should not be directly called by themselves.
Upvotes: 1
Reputation: 15525
As far as I can tell, there are two basic ways to do this.
internal InitInternal()
method that calls a protected virtual Init()
protected internal virtual Init()
, which outside of your assembly automatically becomes a protected
method.Upvotes: 1