Una cosa le soluzioni precedenti ignorano è che ImplementClass può ridefinire MethodToBeCalled e non chiamare MustBeCalled -
public abstract class AbstractClass
{
public abstract void AbstractMethod();
private void MustBeCalled()
{
//will be invoked by MethodToBeCalled();
Console.WriteLine("AbstractClass.MustBeCalled");
}
public void MethodToBeCalled()
{
MustBeCalled();
AbstractMethod();
}
}
public class ImplementClass : AbstractClass
{
public override void AbstractMethod()
{
Console.WriteLine("ImplementClass.InternalAbstractMethod");
}
public new void MethodToBeCalled() {
AbstractMethod();
}
}
Se solo C# consentiti metodi non sovrascritto da sigillare - come parola chiave finale di Java!
L'unico modo che posso pensare di superare questo è utilizzare la delega piuttosto che l'ereditarietà, perché le classi possono essere definite come sigillate. E sto usando uno spazio dei nomi e il modificatore di accesso "interno" per evitare di fornire una nuova implementazione sull'implementazione delle classi. Inoltre, il metodo di override deve essere definito come protetto, altrimenti gli utenti possono chiamarlo direttamente.
namespace Something
{
public sealed class OuterClass
{
private AbstractInnerClass inner;
public OuterClass(AbstractInnerClass inner)
{
this.inner = inner;
}
public void MethodToBeCalled()
{
MustBeCalled();
inner.CalledByOuter();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
System.Console.WriteLine("OuterClass.MustBeCalled");
}
}
public abstract class AbstractInnerClass
{
internal void CalledByOuter()
{
AbstractMethod();
}
protected abstract void AbstractMethod();
}
}
public class ImplementInnerClass : Something.AbstractInnerClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
System.Console.WriteLine("ImplementInnerClass.AbstractMethod");
}
public new void CalledByOuter()
{
System.Console.WriteLine("doesn't work");
}
}
In che modo quando AbstractClass.AbstractMethod viene richiamato dalla classe figlio viene generato un evento per richiamare AbstractClass.MustBeCalled. Ma ancora non sei ancora sicuro di come farlo. – Jeff