Aufruf von base.Dispose() wird automatisch von abgeleiteten Klassen

Bearbeiten - Neue Frage

Ok können formulieren Sie die Frage mehr allgemein.

Mit der spiegelung, gibt es eine Möglichkeit, dynamisch aufrufen zur Laufzeit wird eine Basis-Methode der Klasse, die Sie können überschreiben werden. Sie können nicht mit dem 'base' - Schlüsselwort zur compile-Zeit, da Sie sich nicht sicher sein kann, dass es existiert. Zur Laufzeit möchte ich die Liste meiner Vorfahren Methoden, und nennen Sie die Vorfahr-Methoden.

Versuchte ich mit GetMethods() und solche aber alle, die Sie zurück sind "Zeiger", um die abgeleitete Implementierung der Methode. Nicht eine Umsetzung auf eine Basisklasse.

Hintergrund

Entwickeln wir ein system, in C# 3.0 mit einer relativ großen Klasse Hierarchie. Einige dieser Klassen, überall in der Hierarchie, Ressourcen haben, müssen
entsorgt, diejenigen Umsetzung der IDisposable - Schnittstelle.

Das Problem

Nun, zur Erleichterung der Wartung und refactoring von code würde ich gerne einen Weg finden, für Klassen, die IDisposable implementieren,
auf "automatisch" nennen Basis.Dispose(bDisposing), wenn irgendwelche Vorfahren auch IDisposable implementiert. Wenn auf diesem Weg einige Klasse höher in der Hierarchie beginnt die Umsetzung
oder hält der IDisposable implementiert, wird automatisch erledigt.

Das Problem ist zwei Falten.

  • Zunächst, herauszufinden, ob irgendwelche Vorfahren IDisposable implementiert.
  • Zweiten Aufruf base.Dispose(bDisposing) bedingt.

Den ersten Teil, zu finden über die Vorfahren der IDisposable implementiert, die ich in der Lage gewesen zu bewältigen.

Der zweite Teil ist der "tricky". Trotz all meiner
die Bemühungen, ich habe nicht in der Lage zu nennen base.Dispose(bDisposing) von einer abgeleiteten Klasse. Alle meine versuche fehlgeschlagen. Entweder Sie verursachten
Kompilierung Fehler oder rief die falschen Dispose () - Methode, die meisten abgeleitet, um die Schleife für immer.

Das Hauptproblem ist, dass Sie kann nicht beziehen sich eigentlich auf Basis.Dispose() direkt in Ihrem code, wenn es keine solche Sache wie ein
Vorfahren der Umsetzung (daran erinnert werden, dass es vielleicht keine Vorfahren noch der IDisposable implementiert, aber ich will den abgeleiteten code, um bereit zu sein, Wann und ob eine solche
eine Sache in der Zukunft passiert
). Lassen Sie uns mit der Reflexion Mechanismen, aber ich habe nicht gefunden, eine richtige Weg, es zu tun. Unser code ist ziemlich gefüllt mit
erweiterte Reflexions-Techniken, und ich denke, dass ich nicht verpassen nichts offensichtlich dort.

Meine Lösung

Mein bestes war noch einige bedingte code Verwendung im code auskommentiert. Ändern der IDisposable-Hierarchie würden die entweder brechen die build -
(wenn keine IDisposable Vorfahren vorhanden) oder eine exception werfen (wenn es IDisposable Vorfahren, sondern base.Entsorgen ist nicht genannt).

Hier ist etwas code, den ich Beitrag bin, um zu zeigen, was meine Dispose(bDisposing) - Methode aussieht. Ich Stelle in diesem code am Ende der Dispose () -
Methoden in der gesamten Hierarchie. Alle neuen Klassen sind erstellt aus Vorlagen, die auch diesen code.

public class MyOtherClassBase
{
    //...
}


public class MyDerivedClass : MyOtherClassBase, ICalibrable
{

    private bool m_bDisposed = false;

    ~MyDerivedClass()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool bDisposing)
    {
        if (!m_bDisposed) {
            if (bDisposing) {
                //Dispose managed resources
            }
            //Dispose unmanaged resources
        }
        m_bDisposed = true;

        Type baseType = typeof(MyDerivedClass).BaseType;
        if (baseType != null) {
            if (baseType.GetInterface("IDisposable") != null) {
                //If you have no ancestors implementing base.Dispose(...), comment
                //the following line AND uncomment the throw. 
                //
                //This way, if any of your ancestors decide one day to implement 
                //IDisposable you will know about it right away and proceed to 
                //uncomment the base.Dispose(...) in addition to commenting the throw.
                //base.Dispose(bDisposing);
                throw new ApplicationException("Ancestor base.Dispose(...) not called - " 
                                               + baseType.ToString());
            }
        }
    }
}

So ist, bin ich Fragen, ist es ein Weg, um call-Basis.Dispose() automatisch/bedingt statt?

Mehr Hintergrund

Es ist ein weiterer Mechanismus in der Anwendung, in der alle Objekte erfasst werden, die mit einer main-Klasse. Die Klasse prüft, ob Sie implementieren IDisposable.
Wenn ja, sind Sie ordnungsgemäß zu entsorgen, die von der Anwendung. Dadurch wird vermieden, dass der code durch die Verwendung der Klassen zu beschäftigen
der Aufruf von Dispose() aus ganz von selbst. So, zusätzlich IDisposable zu einer Klasse, die keine Vorfahren Geschichte der IDisposable-funktioniert immer noch perfekt.

Verwenden Sie nicht die C# - Finalizer (ich.e ~MyDerivedClass()) Sie sind nicht-deterministisch und kann nicht ausgeführt werden, manchmal

InformationsquelleAutor Philibert Perusse | 2008-09-16

Schreibe einen Kommentar