An einigen Stellen haben Leute vorgeschlagen, private void Dispose(bool)
für das Muster IDisposable
zu verwenden. Dies scheint jedoch (zumindest für nicht versiegelte Klassen) veraltet zu sein, da das neue vorgeschlagene Muster (nach Microsoft) protected virtual void Dispose(bool)
ist.private void Dispose (bool)?
Die Sache ist, Code-Analyse berichtet nicht private void Dispose(bool)
für Verletzung CA1063, obwohl es scheint, das Muster direkt zu verletzen.
Was ist los? ? Ist private void Dispose(bool)
irgendwie immer genannt (oder etwas zusammengestellt, wie protected virtual Dispose(bool)
sieht
Wenn dies einig Problem mit dem Code-Analyse und ist das falsche Muster, gibt es Möglichkeiten, dies zu erkennen, möglicherweise mit StyleCop
bearbeiten?: nach Prüfung ist es, dass eine Basisklasse base.Dispose()
nennen kann, welche private void Dispose(bool)
getroffen, auch wenn es nicht in der Lage ist, in einem Argument übergeben
Edit:? Beispiel
public class A : IDisposable
{
~A()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) // Should be protected virtual void Dispose(bool)
{
Console.WriteLine("A");
}
}
public class B : A
{
protected virtual void Dispose(bool disposing) // Proper pattern.
{
Console.WriteLine("B");
}
}
public static class Program
{
static void Main(string[] args)
{
A a = new A();
a.Dispose(); // Prints "A"
B b = new B();
b.Dispose(); // Prints "A"!
}
}
Wie Sie sehen können, macht es die Verwendung des Entsorgungsmusters völlig unhandlich.
Sie können dies ein wenig umgehen, indem Sie die public void Dispose(void)
verstecken und dann base.Dispose()
irgendwo anrufen. Dies funktioniert dann "ähnlich" wie das richtige Entsorgungsmuster beim Aufruf B b = new B(); b.dispose();
mit Ausnahme von beim Aufruf A b = new B(); b.Dispose();
, die nur A
Dispose
Methode 10 aufrufen.
public class B : A
{
public void Dispose() // Causes CA error with or without "new".
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) // Proper pattern.
{
base.Dispose(); // Writes "A" (without quotes).
Console.WriteLine("B");
}
}
Grundsätzlich scheint diese ganze Sache schrecklich. Wissen wir, ob es ein Fehler ist, den CA akzeptiert private void Dispose(bool)
und gibt es eine Möglichkeit, eine Warnung mit StyleCop zumindest zu werfen?
Edit: Ich glaube nicht, dass ich Alexandres Antwort akzeptieren sollte, denn relativ zu der Frage, die ich habe, läuft es im Grunde auf "Könnte ein Fehler sein", zusammen mit etwas, das ein Kommentar sein sollte. Wenn jemand anderes etwas Schlüssigeres hat, wäre das meiner Meinung nach eine angemessenere Antwort.
Was ist mit versiegelten Klassen? Geschützt sollte für offene Klassen verwendet werden, private für versiegelte. –
Es funktioniert für beide ist das Problem. Wir fanden ein paar Orte, an denen offene Klassen das Problem nicht anstellten. Das macht jedoch Sinn, dass private für versiegelte Klassen benötigt wird. Trotzdem wäre es nett, wenn CA die Klasse entsiegelt (und das sollte es auch wissen). Ich denke mein Schnitt zeigt, warum es vielleicht nicht ganz aus dem Wald ist, um es nicht zu werfen, aber es ist immer noch ein bisschen nervig. –
Der Aufruf von 'base.Dispose()' wäre eine klare Verletzung des Musters, also glaube ich nicht, dass es das erklärt. Ich stimme Ihrem ursprünglichen Gedanken zu, dass Code Analysis den von Ihnen präsentierten Fall melden sollte. – sstan