前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CA1063:正确实现 IDisposable

CA1063:正确实现 IDisposable

作者头像
呆呆
发布2022-01-10 09:37:31
5720
发布2022-01-10 09:37:31
举报
文章被收录于专栏:centosDai

规则 ID

CA1063

类别

设计

修复是中断修复还是非中断修复

非中断

原因

System.IDisposable 接口无法正确实现。 可能的原因包括:

在类中重新实现 IDisposable。

再次重写 Finalize。

重写 Dispose()。

Dispose() 方法是非公用、已密封或命名为“Dispose”。

Dispose(bool) 未受保护、虚拟或未密封。

在未密封类型中,Dispose() 必须调用 Dispose(true)。

对于未密封的类型,Finalize 实现不调用或不同时调用 Dispose(bool) 或基类终结器。

违反其中任何一个模式都会触发警告 CA1063。

声明和实现 IDisposable 接口的每个未密封类型都必须提供自己的 protected virtual void Dispose(bool) 方法。 Dispose() 应该调用 Dispose(true),而终结器应该调用 Dispose(false)。 如果创建声明和实现 IDisposable 接口的未密封类型,则必须对 Dispose(bool) 进行定义和调用。 有关详细信息,请参阅清理非托管资源(.NET 指南)以及 Dispose 模式。

默认情况下,此规则仅查看外部可见的类型,但这是可配置的。

规则说明

所有的 IDisposable 类型都应正确实现 Dispose 模式。

如何解决冲突

检查代码,并确定以下哪种解决方法能解决此冲突:

从类型实现的接口列表中移除 IDisposable,并重写 Dispose 基类实现。

从类型中移除终结器,重写 Dispose(bool disposing),并在“disposing”为 false 的代码路径中加入终结逻辑。

重写 Dispose(bool disposing),并在“disposing”为 true 的代码路径中加入释放逻辑。

确保将 Dispose() 声明为公用且已密封。

将 dispose 方法重命名为“Dispose”,并确保将其声明为公用且已密封。

确保 Dispose(bool) 声明为受保护、虚拟和未密封。

修改 Dispose(),使其调用 Dispose(true),并在当前对象实例(在 Visual Basic 中为 this 或 Me)上调用 SuppressFinalize,然后返回。

修改终结器,使其调用 Dispose(false),然后返回。

如果创建声明和实现 IDisposable 接口的未密封类型,请确保 IDisposable 的实现遵循本节前面所介绍的模式。

何时禁止显示警告

不禁止显示此规则发出的警告。

配置代码以进行分析

使用下面的选项来配置代码库的哪些部分要运行此规则。

包含特定的 API 图面

你可以仅为此规则、为所有规则或为此类别中的所有规则配置此选项(设计)。 有关详细信息,请参阅代码质量规则配置选项。

包含特定的 API 图面

你可以根据代码库的可访问性,配置要针对其运行此规则的部分。 例如,若要指定规则应仅针对非公共 API 图面运行,请将以下键值对添加到项目中的 .editorconfig 文件:

dotnet_code_quality.CAXXXX.api_surface = private, internal

伪代码示例

以下伪代码提供了有关如何在使用托管资源和本机资源的类中实现 Dispose(bool) 的常规示例。

public class Resource : IDisposable

{

private bool isDisposed;

private IntPtr nativeResource = Marshal.AllocHGlobal(100);

private AnotherResource managedResource = new AnotherResource();

// Dispose() calls Dispose(true)

public void Dispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

// The bulk of the clean-up code is implemented in Dispose(bool)

protected virtual void Dispose(bool disposing)

{

if (isDisposed) return;

if (disposing)

{

// free managed resources

managedResource.Dispose();

}

// free native resources if there are any.

if (nativeResource != IntPtr.Zero)

{

Marshal.FreeHGlobal(nativeResource);

nativeResource = IntPtr.Zero;

}

isDisposed = true;

}

// NOTE: Leave out the finalizer altogether if this class doesn't

// own unmanaged resources, but leave the other methods

// exactly as they are.

~Resource()

{

// Finalizer calls Dispose(false)

Dispose(false);

}

}

另请参阅

Dispose 模式(框架设计准则)

清理非托管资源(.NET 指南)

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档