2009-07-17 10 views
7

mam taką sytuację, że gdy AbstractMethod metoda jest wywoływana z ImplementClass Chcę wymusić MustBeCalled metodę w AbstractClass jest wywoływany. Nigdy wcześniej nie spotkałem się z taką sytuacją. Dziękuję Ci!Jak wymusić wywołanie metody (w klasie bazowej) po wywołaniu metody nadpisywania?

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+0

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

Odpowiedz

8

Opcją byłoby mieć klasa abstrakcyjna zrobić wywołanie w ten sposób. W przeciwnym razie nie ma mowy w C#, aby wymagać odziedziczonej klasy do implementacji metody w określony sposób.

public abstract class AbstractClass 
{ 
    public void PerformThisFunction() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 

    //could also be public if desired 
    protected abstract void AbstractMethod(); 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 

Rozwiązanie to tworzy żądaną metodę zwróconą ku publicznego w abstrakcyjnej klasie, dając klasy abstrakcyjne nad tym, jak i w jakiej kolejności rzeczy są nazywane, jednocześnie pozwalając betonu klasy, aby zapewnić potrzebną funkcjonalność.

+0

*** Dziękuję. *** – Jeff

+0

Użyłem tego wzoru również. Uważam, że jest to jeden z wzorców Gang Of Four, ale nie mam tu mojej książki, aby to potwierdzić. – MedicineMan

+0

Co powiesz na wywołanie zdarzenia, gdy zostanie wywołana metoda Base.AbstractMethod()? – Jeff

-1

Dlaczego po prostu nie można wywołać metody w AbstractMethod() klasy narzędzia?

6

Jak o

public abstract class AbstractClass 
{ 
    public void AbstractMethod() 
    { 
     MustBeCalled(); 
     InternalAbstractMethod(); 
    } 

    protected abstract void InternalAbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void InternalAbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+1

W tej implementacji, nie sądzę, że zmusiłeś użytkownika do wywołania MustBeCalled. Kiedy wywoływana jest metoda AbstractClass.AbstractMethod, metoda ImplementClass.AbstractMethod jest wywoływana, ale funkcja MustBeCalled nie jest. Wierzę, że yshuditelu ma lepsze rozwiązanie. – MedicineMan

0

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"); 
    } 
} 
+0

Fakt, że klasa pochodna może śledzić MethodToBeCalled nie będzie stanowić problemu dla kodu, który używa obiektu klasy pochodnej jako klasy bazowej. Sądzę, że hierarchie metod mogłyby zostać ulepszone, gdyby dozwolone były "prywatne, nadpisywalne" metody; Nie wiem, czy istnieje jakiś techniczny powód, dla którego nie mogliby istnieć. Prywatna metoda nadpisywalna może być wywołana tylko z klasy bazowej lub z klasy pochodnej tej samej metody. W związku z tym niemożliwe byłoby wywołanie kodu w implementacji podstawowej, z wyjątkiem wywołania klasy bazowej do wersji najbardziej pochodnej. – supercat

Powiązane problemy