Dans quelques endroits, les gens ont suggéré d'utiliser private void Dispose(bool)
pour le modèle IDisposable
. Cela semble obsolète (du moins pour les classes non scellées), car le nouveau modèle suggéré (selon Microsoft) est protected virtual void Dispose(bool)
. Le fait est que l'analyse de code ne signale pas private void Dispose(bool)
pour avoir violé CA1063, même s'il semble violer le modèle directement.private void Dispose (bool)?
Quoi de neuf? ? Est-ce private void Dispose(bool)
s'en quelque sorte appelé (ou compilé à quelque chose qui ressemble à protected virtual Dispose(bool)
Si cela est une question avec l'analyse du code et le schéma incorrect, sont là des façons de détecter ce Peut-être avec StyleCop
Modifier?: après mûre réflexion, est-ce qu'une classe de base peut appeler base.Dispose()
qui a frappé private void Dispose(bool)
Même si elle ne peut pas passer un argument
Edit:? Exemple
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"!
}
}
Comme vous pouvez le voir, cela rend l'utilisation du modèle de disposition totalement difficile.
Vous pouvez contourner cela un peu en cachant le public void Dispose(void)
puis en appelant le base.Dispose()
quelque part. Cela fonctionne alors "similaire" à la disposition appropriée lors de l'appel B b = new B(); b.dispose();
sauf lors de l'appel A b = new B(); b.Dispose();
, qui appelle seulement la méthode 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");
}
}
Fondamentalement, tout cela semble terrible. Savons-nous s'il s'agit d'un bug que CA accepte private void Dispose(bool)
et y a-t-il un moyen de lancer au moins un avertissement avec StyleCop? Editer: Je ne pense pas que je devrais accepter la réponse d'Alexandre, par rapport à la question que je me pose, il se résume à "Peut-être un bug", avec quelque chose qui devrait être un commentaire. Si quelqu'un d'autre a quelque chose de plus concluant, je pense que ce serait une réponse plus appropriée.
Qu'en est-il des classes scellées? Protégé devrait être utilisé pour les classes ouvertes, privé pour scellé. –
Cela fonctionne pour l'un ou l'autre est le problème. Nous avons trouvé quelques endroits où les classes non scellées ne jetaient pas le problème. Cela a du sens cependant, que privé est requis pour les classes scellées. Pourtant, il serait bon que CA lance si la classe est descellée (et elle devrait le savoir aussi). Je pense que mon montage montre pourquoi il n'est peut-être pas complètement sorti des bois pour qu'il ne jette pas, mais c'est quand même un peu énervant. –
L'appel 'base.Dispose()' serait une violation claire du modèle, donc je ne pense pas qu'il l'explique. Je suis d'accord avec votre pensée originale que l'analyse de code devrait rapporter le cas que vous avez présenté. – sstan