In meinen Klassen implementiere ich IDisposable wie folgt:
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int UserID)
{
id = UserID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
}
In VS2012 heißt es in meiner Codeanalyse, IDisposable korrekt zu implementieren, aber ich bin mir nicht sicher, was ich hier falsch gemacht habe.
Der genaue Text lautet wie folgt:
CA1063 IDisposable korrekt implementieren Stellen Sie eine überschreibbare Implementierung von Dispose (bool) für 'User' bereit oder markieren Sie den Typ als versiegelt. Ein Aufruf von Dispose (false) sollte nur native Ressourcen bereinigen. Ein Aufruf von Dispose (true) sollte sowohl verwaltete als auch native Ressourcen bereinigen. stman User.cs 10
Als Referenz: CA1063: IDisposable korrekt implementieren
Ich habe diese Seite gelesen, aber ich fürchte, ich verstehe nicht wirklich, was hier zu tun ist.
Wenn jemand mehr Lamens erklären kann, was das Problem ist und / oder wie IDisposable implementiert werden sollte, wird das wirklich helfen!
Dispose
?IDispoable
wenn Sie nicht verwalteten Ressourcen zu entsorgen (dies schließt nicht verwalteten Ressourcen , die gewickelt werden (SqlConnection
,FileStream
usw.). Sie können und sollten nicht implementieren ,IDisposable
wenn Sie nur Ressourcen wie hier geschafft haben. Das ist, IMO, Ein großes Problem bei der Code-Analyse. Es ist sehr gut darin, dumme kleine Regeln zu überprüfen, aber nicht gut darin, konzeptionelle Fehler zu überprüfen.Antworten:
Dies wäre die richtige Implementierung, obwohl ich in dem von Ihnen geposteten Code nichts sehe, was Sie entsorgen müssen. Sie müssen nur implementieren,
IDisposable
wenn:Nichts in dem von Ihnen geposteten Code muss entsorgt werden.
quelle
using(){ }
wenn immer möglich zu verwenden, aber um dies zu tun, müssen Sie IDisposable implementieren. Im Allgemeinen bevorzuge ich den Zugriff auf eine Klasse über usings, insb. wenn ich die Klasse nur in ein oder zwei Funktionenusing
Block, wenn die Klasse IDisposable implementiert . Wenn Sie keine Klasse benötigen, um verfügbar zu sein, implementieren Sie sie nicht. Es hat keinen Zweck.using
Blocks ist jedoch in der Regel über dieIDisposable
Schnittstelle hinaus ansprechend . Ich stelle mir vor, dass es mehr als ein paar MissbräucheIDisposable
nur zu Scoping-Zwecken gegeben hat.GC.SuppressFinalize(this);
sinnlos. Wie @mariozski betonte, würde ein Finalizer dazu beitragen, dass dieser überhauptDispose
aufgerufen wird, wenn die Klasse nicht in einemusing
Block verwendet wird.Zunächst müssen Sie
string
s undint
s nicht "bereinigen" - sie werden automatisch vom Garbage Collector erledigt. Das einzige, was bereinigt werden muss,Dispose
sind nicht verwaltete Ressourcen oder verwaltete Ressourcen, die implementiert werdenIDisposable
.Unter der Annahme, dass dies nur eine Lernübung ist, wird empfohlen ,
IDisposable
einen "Sicherheitsverschluss" hinzuzufügen, um sicherzustellen, dass Ressourcen nicht zweimal entsorgt werden:quelle
readonly
Semantik stört )Das folgende Beispiel zeigt die allgemeine Best Practice zum Implementieren der
IDisposable
Schnittstelle. ReferenzDenken Sie daran, dass Sie einen Destruktor (Finalizer) nur benötigen, wenn Sie nicht verwaltete Ressourcen in Ihrer Klasse haben. Wenn Sie einen Destruktor hinzufügen, sollten Sie die Finalisierung in der Entsorgung unterdrücken , da sich Ihre Objekte sonst zwei Speicherzyklen im Speicher befinden (Hinweis: Lesen Sie, wie die Finalisierung funktioniert ). Das folgende Beispiel erläutert alles oben.
quelle
IDisposable
Es gibt eine Möglichkeit, nicht verwaltete Ressourcen zu bereinigen, die vom Garbage Collector nicht automatisch bereinigt werden.Alle Ressourcen, die Sie "bereinigen", sind verwaltete Ressourcen, und als solche erreicht Ihre
Dispose
Methode nichts. Ihre Klasse sollte überhaupt nicht implementierenIDisposable
. Der Garbage Collector kümmert sich selbstständig um all diese Felder.quelle
Sie müssen das Einwegmuster wie folgt verwenden:
quelle
SafeHandle
(und Untertypen). Bei verwalteten Ressourcen wird die ordnungsgemäße Entsorgung viel einfacher. Sie können den Code auf eine einfache Implementierung dervoid Dispose()
Methode reduzieren.Sie müssen Ihre
User
Klasse nicht ausführen ,IDisposable
da die Klasse keine nicht verwalteten Ressourcen (Datei, Datenbankverbindung usw.) erhält . Normalerweise markieren wir Klassen so, alsIDisposable
hätten sie mindestens einIDisposable
Feld oder / und eine Eigenschaft. Sagen Sie es bei der ImplementierungIDisposable
besser nach dem typischen Microsoft-Schema:quelle
Idisposable wird immer dann implementiert, wenn Sie eine deterministische (bestätigte) Speicherbereinigung wünschen.
Verwenden Sie beim Erstellen und Verwenden der Users-Klasse den Block "using", um zu vermeiden, dass die dispose-Methode explizit aufgerufen wird:
Das Ende des mit dem Benutzerobjekt erstellten Verwendungsblocks wird durch implizites Aufrufen der Entsorgungsmethode entsorgt.
quelle
Ich sehe viele Beispiele für das Microsoft Dispose-Muster, das wirklich ein Anti-Muster ist. Wie viele darauf hingewiesen haben, erfordert der Code in der Frage überhaupt keine IDisposable. Wenn Sie es jedoch implementieren möchten, verwenden Sie bitte nicht das Microsoft-Muster. Eine bessere Antwort wäre, den Vorschlägen in diesem Artikel zu folgen:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
Das einzige andere, was wahrscheinlich hilfreich wäre, ist die Unterdrückung dieser Warnung zur Codeanalyse ... https://docs.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs- 2017
quelle