В нескольких местах люди предложили использовать private void Dispose(bool)
для шаблона IDisposable
. Это кажется устаревшим хотя (по крайней мере для незапечатанных классов), поскольку новый предложенный шаблон (согласно Microsoft) - protected virtual void Dispose(bool)
.private void Dispose (bool)?
Дело в том, что Code Analysis не сообщает private void Dispose(bool)
за нарушение CA1063, даже если оно, похоже, нарушает шаблон напрямую.
Что случилось с этим? ? Является ли private void Dispose(bool)
как-то вызывлся (или скомпилирован к чему-то, что выглядит как protected virtual Dispose(bool)
Если это какой-то вопрос с анализом кода и неправильная картина, есть способы, чтобы обнаружить это Возможно с StyleCop
Edit?: После рассмотрения, это, что базовый класс может назвать base.Dispose()
, который ударит private void Dispose(bool)
Даже если он не в состоянии передать в качестве аргумента
Edit:? Sample
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"!
}
}
Как вы можете видеть из этого, это делает использование шаблона размещения полностью громоздким.
Вы можете обойти это немного, спрятав public void Dispose(void)
и затем позвонив base.Dispose()
. Затем это работает «аналогично» правильному шаблону утилизации при вызове B b = new B(); b.dispose();
, за исключением при вызове A b = new B(); b.Dispose();
, который вызывает только A
метод Dispose
.
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");
}
}
В целом, все это кажется ужасным. Знаем ли мы, является ли это ошибкой, что CA принимает private void Dispose(bool)
и есть ли способ хотя бы бросить предупреждение с помощью StyleCop?
Редактировать: Я не думаю, что я должен согласиться с ответом Александра, поскольку относительно вопроса, который у меня есть, в основном сводится к «Может быть ошибка», а также что-то, что должно быть комментарием. Если у кого-то еще есть что-то более убедительное, я думаю, что это будет более подходящий ответ.
Что относительно закрытых классов? Защищенный должен использоваться для открытых классов, для закрытых. –
Это работает для любого вопроса. Мы обнаружили несколько мест, где непечатаемые классы не бросали проблему. Это имеет смысл, однако, что частный требуется для закрытых классов. Тем не менее, было бы неплохо, если бы CA выбросил, если класс был вскрыт (и он также должен это знать). Я думаю, что мое редактирование показывает, почему он не может быть полностью из леса, чтобы он не бросал, но это все еще немного раздражает. –
Вызов 'base.Dispose()' будет явным нарушением шаблона, поэтому я не думаю, что он его объясняет. Я согласен с вашей оригинальной мыслью, что Code Analysis должен сообщить о вашем случае. – sstan