CA2213: Atılabilen alanlar atılmalıdır
Özellik | Değer |
---|---|
Kural Kimliği | CA2213 |
Başlık | Atılabilen alanlar atılmalıdır |
Kategori | Kullanım |
Hataya neden olan veya bozulmayan düzeltme | Hataya neden olmayan |
.NET 9'da varsayılan olarak etkin | Hayır |
Neden
uygulayan System.IDisposable bir tür, aynı zamanda uygulayan IDisposabletürlerdeki alanları bildirir. Dispose alanın yöntemi, bildirim türü yöntemi tarafından Dispose çağrılmaz.
Kural açıklaması
Bir tür, yönetilmeyen tüm kaynaklarının atılmasından sorumludur. Kural CA2213, atılabilir bir türün (yani uygulayanIDisposable) T
atılabilir türün FT
örneği olan bir alan F
bildirip bildirmediğini denetler. İçeren türündeki T
yöntemler veya başlatıcılar içinde yerel olarak oluşturulmuş bir nesneye atanan her alan F
için, kural öğesine bir çağrı FT.Dispose
bulmaya çalışır. Kural tarafından ve bir düzey daha düşük olarak adlandırılan yöntemleri (tarafından çağrılan T.Dispose
yöntemler tarafından çağrılan yöntemler T.Dispose
) arar.
Not
Özel durumlar dışında, kural CA2213 yalnızca içeren türün yöntemleri ve başlatıcıları içinde yerel olarak oluşturulmuş bir atılabilir nesne atanmış alanlar için tetiklenir. Nesne türü dışında T
oluşturulur veya atanırsa, kural tetiklenmez. Bu, içeren türün nesnenin atılmasıyla ilgili sorumluluğun olmadığı durumlarda gürültüyü azaltır.
Özel durumlar
Kural CA2213, atandıkları nesne yerel olarak oluşturulmasa bile aşağıdaki türlerdeki alanlar için de tetiklenebilir:
Bu türlerden birinin nesnesini bir oluşturucuya geçirip bir alana atamak, yeni oluşturulan türe bir atma sahiplik aktarımını gösterir. Yani, yeni yapılan tür artık nesnenin atılmasından sorumludur. Nesne atılmazsa CA2213 ihlali oluşur.
İhlalleri düzeltme
Bu kuralın ihlalini düzeltmek için, uygulayan IDisposabletürlerdeki alanları çağırınDispose.
Uyarıların ne zaman bastırılması gerekiyor?
Aşağıdakiler durumunda bu kuraldan gelen bir uyarıyı engellemek güvenlidir:
- Bayraklı tür, alan tarafından tutulan kaynağı serbest bırakmakla sorumlu değildir (başka bir ifadeyle türün atma sahipliği yoktur)
- çağrısı Dispose , kural denetimlerinden daha derin bir çağrı düzeyinde gerçekleşir
- alanlarının atma sahipliği, içeren tür tarafından tutulmaz.
Uyarıyı gizleme
Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.
#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini none
olarak ayarlayın.
[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none
Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.
Örnek
Aşağıdaki kod parçacığında uygulayan bir tür TypeA
gösterilmektedir IDisposable.
public class TypeA : IDisposable
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed resources
}
// Free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Disposable types implement a finalizer.
~TypeA()
{
Dispose(false);
}
}
Aşağıdaki kod parçacığı, bir alanı atılabilir bir tür (TypeA
) olarak bildirerek ve alanı aFieldOfADisposableType
çağırmayarak Dispose CA2213 kuralını ihlal eden bir tür TypeB
gösterir.
public class TypeB : IDisposable
{
// Assume this type has some unmanaged resources.
TypeA aFieldOfADisposableType = new TypeA();
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
// Violates rule: DisposableFieldsShouldBeDisposed.
// Should call aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
public void Dispose()
{
if (!disposed)
{
// Dispose of resources held by this instance.
Dispose(true);
}
}
// Disposable types implement a finalizer.
~TypeB()
{
Dispose(false);
}
}
İhlali düzeltmek için atılabilir alanı arayın Dispose()
:
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}