2017-04-08 3 views
0

Ich bin ein wenig Mühe, das Verständnis der IDisposable-SchnittstelleImplementierung von IDisposable C#

ich eine Game Engine entwickelt und haben Codeanalyse auf meine Lösung lief und gesagt worden, die IDisposable-Schnittstelle auf meiner „GrapicsEngine“ Klasse zu implementieren , weil es eine Bitmap-Instanz enthält.

Natürlich habe ich suchte im Internet zu lernen, wie man diese richtig zu tun und haben kam mit dem folgenden Code auf:

Hier ist meine Klasse Mitglieder:

private const int BITMAP_WIDTH = 4096; 
private const int BITMAP_HEIGHT = 4096; 

private Graphics backBuffer; 
private Bitmap bitmap; 

private Color clearColor; 

private WindowSurface surface; 

private GraphicsQuality quality; 

private Viewport viewport; 

und hier ist mein IDispoable Region:

#region IDisposable 

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

protected virtual void Dispose(bool disposing) 
{ 
    if (disposing == true) 
     ReleaseManagedResources(); 

    ReleaseUnmanagedResources(); 
} 

private void ReleaseManagedResources() 
{ 
    if (bitmap != null) 
     bitmap.Dispose(); 
    if (backBuffer != null) 
     backBuffer.Dispose(); 
} 

private void ReleaseUnmanagedResources() 
{ 

} 

~GraphicsEngine() 
{ 
    Dispose(false); 
} 

#endregion 

Beachten Sie, dass WindowSurface ein WinForm-Panel ist, GraphicsQuality ein Enum ist und Viewport nur int-Werte enthält.

So habe ich nur ein paar Fragen:

  1. Bin ich richtig meine Ressourcen entsorgen?
  2. Welche Ressourcen muss ich in der Methode Unmanaged resources entsorgen?
  3. Wenn ich eine neue Klasse erstelle und sie meine GraphicsEngine-Klasse enthält, sollte diese Klasse IDisposable ebenfalls implementieren?

Jede Hilfe zu diesem Thema würde sehr geschätzt werden.

Antwort

3

Sie sind auf dem richtigen Weg. Immer wenn Sie eine Variable auf Klassenebene haben, die wegwerfbar ist, sollte die enthaltende Klasse auch wegwerfbar sein. Und du verstehst es richtig von dem, was ich sagen kann. Ich sehe keine Klassennamenzeile, daher kann ich nicht sagen, ob die IDisposable-Schnittstelle enthalten ist, aber ich kann mir vorstellen, dass Sie dies tun, seit Sie die Methoden implementiert haben. Wenn nicht, stelle sicher, dass du es hinzufügst.
IDisposable ist eine Kettenreaktionsart der Implementierung. Wenn die Variable wegwerfbar ist und nur für einen Methodenaufruf lokal ist, dann haben Sie sie am Ende des Aufrufs, aber wenn sie auf Klassenebene ist, implementieren Sie IDisposable und entsorgen sie mit Ihrer Klasse, wie Sie es tun. Auf diese Weise kann jeder, der Ihre Klasse benutzt, es ordnungsgemäß entsorgen.

zum Beispiel so: Angenommen, ich eine Datei in meiner Klasse geöffnet haben ...

public class MyClass 
{ 
    private File txtFile = File.Create(...) 
} 

Jetzt jemand meine Klasse verwendet.

private void useClass() 
{ 
    var myClass = new MyClass(); 
} 

Nun, sie haben gerade eine Datei geöffnet und es wurde nicht ordnungsgemäß entsorgt.

Ändern Sie den Code, und es kann wie so verwendet werden ...

public class MyClass : IDisposable 
{ 
    private File txtFile = new File.Create(...) 

    public void Dispose() 
    { 
      txtFile.Dispose(); 
    } 
} 

Und wenn die Verwendung es sie kann es wie so verwenden ...

private void useClass() 
{ 
    using (var myClass = new MyClass()) 
    { 
     //some code 
    } 
} 

Hoffentlich beantwortet Ihre Fragen . Denken Sie daran, dass Sie ein Disposable-Objekt für eine Methode deklarieren, dann müssen Sie IDisposable in Ihrer Klasse nicht implementieren, da Sie es in dieser Methode entsorgen werden.Aber wenn Sie es auf Klassenebene implementieren, ob Sie über eine Methode verfügen, die es entsorgt oder nicht, sollten Sie IDisposable implementieren und sicherstellen, dass es entsorgt wird, wenn das, das Klassenaufrufe enthält, entsorgt wird. Sinn ergeben? Hoffe, das hilft.

+0

Ich denke, ich verstehe jetzt. Nur eine letzte Frage: Ich habe eine Sprite-Klasse, die eine Bitmap enthält, die einen öffentlichen Getter und Setter hat, sollte dieser Aufruf auch IDisposable implementieren, oder sollte ich die Bitmap einfach wie "sprite.bitmap.Dispose" bei Bedarf entsorgen? Ich stelle mir vor, es ist das Letztere. –

+0

Posten Sie den Teil des Codes und ich werde es Ihnen sagen. Wenn Sie das Einwegobjekt durch eine Eigenschaft (Getter/Setter) zurückführen, ist das Objekt selbst entsorgbar, und jeder, der diese Eigenschaft verwendet, hat die Möglichkeit, es auch mit Einmalfunktionen zu verwenden. Aber noch einmal, ja, da dies auf Klassenebene ist, wollen Sie es immer noch in Ihrer Klasse implementieren und entsorgen. –

+0

Ich denke, ich verstehe jetzt danke. Eine letzte Frage, ich habe eine Liste von Frames für Animationen, ein Frame enthält eine Bitmap. Wenn ich über die Rahmen verfüge (indem ich durch die Liste iteriere), wenn es darum geht, nicht verwaltete Ressourcen zu entsorgen, würde ich dann meine Liste löschen? –