Muss ich während der Klasseninstanz alle IDisposable-Member explizit entsorgen?

8

Ich habe eine Klasse, die eine Eigenschaft vom Typ SqlConnection hat. SqlConnection implementiert IDisposable . Ich habe folgende Fragen:

  1. Sollte meine Klasse auch IDisposable implementieren, nur weil sie eine Eigenschaft vom Typ IDisposable ?
  2. hat?
  3. Wenn ja, muss ich die Eigenschaft explizit entsorgen, wenn ich die Instanz meiner Klasse vertreibe? ZB

    %Vor%

Hinweis: Ich weiß, dass bei der Implementierung von IDisposable ein Muster zu beachten ist, aber meine Frage ist sehr spezifisch für den oben genannten Fall.

    
Learner 03.08.2015, 09:05
quelle

3 Antworten

4

Es hängt ab. Wenn Ihre Klasse erstellt und besitzt muss die IDisposable es über sie verfügen (also sind beide Antworten "ja" ). Wenn Ihre Klasse nur IDisposable verwendet darf sie nicht disponieren (also lautet die erste Antwort normalerweise "nein" und die zweite Antwort) ist "nein" ).

In Ihrem Fall scheint Helper class

zu sein %Vor%

just verwendet SqlConnection (weil es "set" bereitstellt) wie

%Vor%

Damit die Verbindung nicht trennen kann . Im Gegenteil, eine Klasse wie diese

%Vor%

besitzt seine SqlConnection , so dass es für die Entsorgung verantwortlich ist:

%Vor%     
Dmitry Bychenko 03.08.2015, 09:47
quelle
6
  1. Ja

  2. Ja

Dafür gibt es sogar eine Regel für die Code-Analyse: CA1001: Typen, die Einwegfelder besitzen, sollten wegwerfbar sein .

  

Eine Klasse implementiert die IDisposable-Schnittstelle, über die nicht verwaltet werden kann   Ressourcen, die es besitzt. Ein Instanzfeld, das ein IDisposable-Typ ist   zeigt an, dass das Feld eine nicht verwaltete Ressource besitzt. Eine Klasse, die   erklärt, dass ein IDisposable-Feld indirekt eine nicht verwaltete Ressource besitzt   und sollte die IDisposable-Schnittstelle implementieren.

BEARBEITEN: Die obige Antwort ist immer gültig für IDisposable -Member, die im Besitz der übergeordneten Klasse sind .

Das heißt, das Eigentumsrecht eines Mitglieds ist für öffentliche Objekte wie Ihres ziemlich vage: Wenn die SqlConnection Instanz außerhalb Ihrer Klasse erstellt wird, ist Ihre Klasse wahrscheinlich nicht Eigentümer der Instanz, aber niemand weiß das außer Ihnen.

Es gibt ein lustiges Beispiel darüber, ob ein IDisposable -Mitglied im Besitz ist oder nicht, indem es seine Elternklasse verwendet: StreamWriter . Es gibt viele Fragen dazu, siehe zum Beispiel diesen Thread: Gibt es eine Möglichkeit, einen StreamWriter zu schließen, ohne den BaseStream zu schließen?

Jetzt gibt es sogar einen leaveOpen -Parameter, so dass der StreamWriter seinen Basisdatenstrom nicht zur Verfügung stellt.

    
ken2k 03.08.2015 09:13
quelle
1

Ja für beide - Wenn Ihre Klasse für den Lebenszyklus eines Mitgliedsfeldes verantwortlich ist, muss sie Dispose für dieses Objekt aufrufen, was bedeutet, dass Ihre Klasse IDisposable implementieren muss, damit das Mitglied entsorgt werden kann die richtige Zeit.

Beachten Sie jedoch, dass Sie wahrscheinlich keine öffentlich einstellbare Eigenschaft für ein solches Mitglied verwenden möchten, da dann jeder das Feld direkt löschen, löschen, löschen und zurücksetzen kann. Ihre Klasse muss die Kontrolle über dieses Feld behalten, was bedeutet, dass sie nur innerhalb der Klasse selbst einstellbar sein sollte - idealerweise mit einem private readonly -Feld oder einer readonly -Eigenschaft.

    
thecoop 03.08.2015 09:10
quelle