In un paio di punti, le persone hanno suggerito di utilizzare private void Dispose(bool)
per il modello IDisposable
. Ciò sembra superato (almeno per le classi non sigillate), poiché il nuovo modello suggerito (secondo Microsoft) è protected virtual void Dispose(bool)
.vuoto privato Dispose (bool)?
Il fatto è che Code Analysis non segnala private void Dispose(bool)
per violazione di CA1063, anche se sembra violare direttamente il modello.
Che succede? ? È private void Dispose(bool)
in qualche modo sempre chiamato (o compilato a qualcosa che assomiglia a protected virtual Dispose(bool)
Se questo è qualche problema con analisi del codice ed è il modello corretto, ci sono modi per rilevare questo Possibilmente con StyleCop
Edit??: dopo considerazione, è che una classe base può chiamare base.Dispose()
che ha colpito private void Dispose(bool)
Anche se non è in grado di passare in un argomento
Edit:? Esempio
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"!
}
}
Come potete vedere da questo, rende l'uso del modello di smaltimento totalmente ingombrante.
È possibile aggirare questo un po 'nascondendo il public void Dispose(void)
e quindi chiamando base.Dispose()
da qualche parte. Questo funziona quindi "simile" al modello di smaltimento corretto quando si chiama B b = new B(); b.dispose();
eccetto quando si chiama A b = new B(); b.Dispose();
, che chiama solo il metodo Dispose
A
.
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");
}
}
Fondamentalmente, questa faccenda sembra terribile. Sappiamo se è un bug che CA accetta private void Dispose(bool)
e c'è un modo per lanciare un avvertimento almeno con StyleCop?
Edit: Non penso che dovrei accettare la risposta di Alexandre, in quanto relativa alla domanda che ho sostanzialmente si riduce a "Potrebbe essere un bug", insieme a qualcosa che dovrebbe essere un commento. Se qualcun altro ha qualcosa di più decisivo, penso che sarebbe una risposta più appropriata.
E le lezioni sigillate? Protetto dovrebbe essere utilizzato per le classi aperte, private per sealed. –
Funziona per entrambi è il problema. Abbiamo trovato un paio di posti in cui le classi non sigillate non stavano gettando il problema. Ciò ha un senso, però, che il privato è richiesto per le classi sigillate. Tuttavia, sarebbe bello che la CA si lanci se la classe non è sigillata (e dovrebbe anche saperlo). Penso che la mia modifica mostri perché potrebbe non essere completamente fuori dal bosco perché non si possa lanciare, ma è comunque un po 'fastidioso. –
Chiamare 'base.Dispose()' sarebbe una chiara violazione del pattern, quindi non penso che lo spieghi. Sono d'accordo con il tuo pensiero originale che l'analisi del codice dovrebbe riportare il caso che hai presentato. – sstan