Jedno powyższe rozwiązania jest to, że ignorują ImplementClass można przedefiniować MethodToBeCalled i nie nazywają 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();
}
}
Jeśli tylko C# dozwolone metody non-przesłonięte być uszczelnione - jak końcowego hasła Java!
Jedyny sposób, w jaki mogę go pokonać, to użycie delegacji zamiast dziedziczenia, ponieważ klasy mogą być zdefiniowane jako zamknięte w postaci. Używam przestrzeni nazw i "wewnętrznego" modyfikatora dostępu, aby zapobiec wprowadzeniu nowej implementacji w implementowaniu klas. Ponadto metoda nadpisywania musi być zdefiniowana jako chroniona, w przeciwnym razie użytkownicy mogliby ją wywołać bezpośrednio.
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");
}
}
Co zrobić, gdy klasa AbstractClass.AbstractMethod jest wywoływana przez klasę potomną, zdarzenie jest wywoływane w celu wywołania metody AbstractClass.MustBeCalled. Ale znowu nie wiem, jak to zrobić. – Jeff