Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
| Свойство | Значение |
|---|---|
| Идентификатор правила | CA1816 |
| Заголовок | Вызов GC.SuppressFinalize должен осуществляться правильно |
| Категория | Использование |
| Исправление является критическим или не критическим | неразрывный |
| Включен по умолчанию в .NET 10 | Как предложение |
| Применимые языки | C# и Visual Basic |
Причина
Нарушения этого правила могут быть вызваны следующими причинами:
В незапечатанном классе метод, который является реализацией IDisposable.Dispose, и не вызывает GC.SuppressFinalize.
Метод, который не является реализацией IDisposable.Dispose и вызывает GC.SuppressFinalize.
Метод, который вызывает GC.SuppressFinalize и передает нечто, отличное от this (C#) или Me (Visual Basic).
Описание правила
Этот IDisposable.Dispose метод позволяет пользователям освобождать ресурсы в любое время, прежде чем объект станет доступным для сборки мусора. При вызове метода IDisposable.Dispose он освобождает ресурсы объекта. Это делает завершение ненужным. IDisposable.Dispose должен вызывать GC.SuppressFinalize, чтобы сборщик мусора не вызывал финализатор объекта.
Чтобы производным типам с финализаторами не приходилось повторно реализовывать IDisposable и вызывать его, незапечатанные типы без финализаторов должны также вызывать GC.SuppressFinalize.
Устранение нарушений
Чтобы устранить нарушение этого правила:
Если метод является реализацией Dispose, добавьте вызов GC.SuppressFinalize.
Если метод не является реализацией Dispose, удалите вызов GC.SuppressFinalize или переместите его в реализацию Dispose типа.
Измените все вызовы GC.SuppressFinalize, чтобы передать this (C#) или Me (Visual Basic).
Если тип не должен быть переопределен, пометьте его как
sealed.
Когда лучше отключить предупреждения
Только подавляйте предупреждение из этого правила, если вы намеренно используете GC.SuppressFinalize для управления временем существования других объектов. Не подавляйте предупреждение для этого правила, если реализация Dispose не вызывает GC.SuppressFinalize. В этом случае невозможность отключить завершение работы ухудшает производительность и не дает никаких преимуществ.
Отключение предупреждений
Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none в файле конфигурации.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.
Пример нарушения CA1816.
В этом коде показан метод, который вызывает GC.SuppressFinalize, но не передает this (C#) или Me (Visual Basic). В результате этот код нарушает правило CA1816.
Public Class MyStreamClass
Implements IDisposable
Private _stream As New MemoryStream
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' Violates rule.
GC.SuppressFinalize(True)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _stream IsNot Nothing Then
_stream.Dispose()
_stream = Nothing
End If
End If
End Sub
End Class
public class MyStreamClass : IDisposable
{
private MemoryStream? _stream = new();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true); // Violates rule
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_stream?.Dispose();
_stream = null;
}
}
}
Пример, соответствующий CA1816.
В этом примере показан метод, который правильно вызывает GC.SuppressFinalize путем передачи this (C#) или Me (Visual Basic).
Public Class MyStreamClass
Implements IDisposable
Private _stream As New MemoryStream
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _stream IsNot Nothing Then
_stream.Dispose()
_stream = Nothing
End If
End If
End Sub
End Class
public class MyStreamClass : IDisposable
{
private MemoryStream? _stream = new();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_stream?.Dispose();
_stream = null;
}
}
}
Связанные правила
- CA2215: методы Dispose должны вызывать метод Dispose базового класса
- CA2216: высвобождаемые типы должны объявлять метод завершения