为什么“密封”会影响 IDisposable 的实现?

2023-12-10

看完答案后here,我决定将我的课程标记为密封以简化I一次性执行。为什么sealed会影响IDisposable的实现(例如GC.SuppressFinalize(this);不需要调用)?请解释发生了什么事。我需要能够向其他开发人员解释为什么我要密封该类。


如果一个类实现了IDisposable没有密封,派生类可能需要做一些事情来响应Dispose,但是基类动作Dispose也应该执行。如果该类公开了 publicDispose永远是同义词的成员IDisposable.Dispose,通过简单地使用带有公共虚拟的隐式接口实现,可以在 C# 中实现必要的语义Dispose method.

这种方法有两个问题:

  1. 它要求派生类在父类公开公共“Dispose”方法的情况下使用与不公开“Dispose”方法的情况不同的方法;如果一个不公开“Dispose”方法的类被一个公开“Dispose”方法的未密封类继承,那么事情可能会变得非常混乱。
  2. 一些基本处理代码应该在派生类处理代码之前运行(例如,禁止重复尝试“Dispose”的代码),而有些则应该在派生类处理代码之后运行(例如“GC.SuppressFinalize()”)。实现这一点的唯一方法是让非虚拟包装器调用受保护的虚拟函数。请注意,顺便说一句,微软的包装器不能正确抑制重复的“Dispose”,但包装器是此类抑制代码的唯一好地方。

请注意,微软似乎有意Dispose在基类不重写的情况下使用的模式Finalize,但派生类使用Finalize用于清理。虽然这可能是意图,但这并不是一个好的模式。除了极少数例外,唯一应该重写的类Finalize用于清理的是那些派生自琐碎类的类,例如Object。如果一个类实现了IDisposable但不覆盖Finalize,派生类应该重写的唯一目的Finalize是发出警报,如果Finalize曾经被调用过,甚至这种用法也是有争议的(更好的模式是:



class whatever:IDisposable
{
  IDisposable DisposedStatusObject;
  // Generate a static dummy object instance we can use as a sentinel value
  // It needs to be `IDisposable`, but shouldn't actually hold any resources.

  static IDisposable DisposedStatusDisposed = new List<int>().GetEnumerator();

  public bool Disposed {get {return (DisposedStatusObject == DisposedStatusDisposed);} }

  whatever()
  {
    DisposedStatusObject = new DisposalAlarm(); // First thing in constructor
  }
  void Dispose()
  {
    IDisposable prevStatus;
    prevStatus = Interlocked.Exchange(DisposedStatus, DisposedStatusDisposed);
    if (prevStatus != DisposedStatusDisposed)
    {
      Dispose(true);
      prevStatus.Dispose();
    }
  }
}
  

The DisposalAlarm()假设类是一个被重写的类Finalize()如果出现这种情况,则发出警报的方法Finalize()方法在没有它的情况下被调用Dispose()首先调用的方法。这Dispose方法用于whatever将确保,如果派生类方法正确返回,则警报将被取消。请注意,如果一个实例whatever有一个不受抑制的终结器,一切都whatever持有直接或间接引用的对象必须保留,直到终结器运行或被抑制。相比之下,添加一个DisposalAlarm对象不会延长任何对象的生命周期whatever.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么“密封”会影响 IDisposable 的实现? 的相关文章

  • 如何将对 System.Data.DataSetExtensions 的引用添加到网站 ascx.cs 文件?

    我们正在处理一个网站项目并尝试参考System Data DataSetExtensions 使用 Web 应用程序会更好 不过 技术主管有她的理由 这是我们尝试过的 找到装配路径 打开 Visual Studio 命令提示符并运行sn e
  • Silverlight 4 PLINQ

    我有一个非常简单的问题 是否可以将 PLINQ 与 Silverlight 4 一起使用 因为它似乎不存在于最常引用的程序集中 它不受支持 但您可以在这里投票 http dotnet uservoice com forums 4325 si
  • 如何更改 .NET MAUI Blazor 项目中的默认字体?

    我有一个用于 NET MAUI Blazor 应用程序的默认 Visual Studio 项目 针对 Windows x64 构建 我尝试了两种不同的更改字体的方法 在MauiProgram cs中有一个字体的配置ConfigureFont
  • 使用AOP技术拦截ADO.Net

    我有相当大的代码库 使用各种不同的 ADO 技术 即一些 EF 在某些情况下直接使用 ADO Net 我想知道是否有任何方法可以全局拦截任何 ADO Net 调用 以便我可以开始审核信息 例如执行的确切 SQL 语句 花费的时间 返回的结果
  • 使用“new()”和“.StartNew()”创建新实例有什么区别?

    来自我对问题的 回答 任务中的秒表似乎在所有任务中都是累加的 只想测量任务间隔 https stackoverflow com a 16259019 200449 创建新的项目之间可能存在哪些差异跑表 http msdn microsoft
  • HtmlAgilityPack XPath 大小写忽略

    当我使用 SelectSingleNode meta name keywords 它不起作用 但是当我使用原始文档中使用的相同案例时 效果很好 SelectSingleNode meta name Keywords 那么问题是如何设置忽略大
  • 使用 TCP 套接字在本地代理视频

    我一直对向媒体浏览器添加对视频播客的支持非常感兴趣 我希望用户能够浏览可用的视频播客并从互联网上流式传输它们 这真的很容易 因为媒体播放器等将愉快地播放存在于云中的文件 问题是我想在本地缓存这些文件 因此同一集的后续观看将不涉及流式传输 而
  • RichTextbox SelectionStart 返回错误的索引

    我需要向用户显示光标上文本的选择开始和长度 就像在 notepad exe 中一样 选择长度没有问题 因为 Richtextbox 支持带有开始和结束的选择属性 http msdn microsoft com en us library s
  • 等待运算符错误

    我的代码有问题 我怎么解决这个问题 这个问题出现在await操作符中 public MyModel HttpClient client new HttpClient HttpResponseMessage response await cl
  • 更改实体的可访问性

    我想建立一个内部实体 我已将实体 其标量属性和导航属性更改为内部 当我尝试构建它时出现此错误 错误 6036 EntityType 文件 具有 内部 可访问性 EntitySet 文件 具有具有 公共 可访问性的 get 属性 Entity
  • 检查 SSRS 报告自定义代码中的 Active Directory 组成员资格表单

    我正在构建 SQL Server Reporting Services SSRS 报告 查看报告的最终用户可以选择某些输入参数 在本例中为位置 用户可以选择的位置取决于 Active Directory 组成员身份 因此我尝试在自定义报告功
  • LINQ to Entities 无法识别“Int32 IndexOf(System.String, System.StringComparison)”方法

    我已经使用 Entityframework 执行了 linq 查询 如下所示 GroupMaster getGroup null getGroup DataContext Groups FirstOrDefault item gt keyw
  • 将集合项复制到 .NET 中的另一个集合

    在 NET VB 中 如何获取一个集合中的所有项目 并将它们添加到第二个集合中 而不丢失第二个集合中预先存在的项目 我正在寻找比这更有效的东西 For Each item As Host In hostCollection1 hostCol
  • 如何更改 Settings.settings 值的值

    我有一个简单的控制台应用程序 每天运行 由 Windows 任务计划程序调用 并且取决于每次应用程序运行时递增的值 为了保留这个值 我选择使用 Settings Settings 文件 因此 我有一个名为 RunNumber 和 Scope
  • 将参数传递给模板类型的 C# 泛型 new()

    添加到列表时 我试图通过其构造函数创建一个 T 类型的新对象 我收到编译错误 错误消息是 T 创建变量实例时无法提供参数 但我的类确实有一个构造函数参数 我怎样才能做到这一点 public static string GetAllItems
  • 使用 HttpClient 从 webapi 消费 xml

    我使用 WebClient 从 Restfull 服务 net web api 获取 Xml 对象 一切都运行良好 using WebClient client new WebClient client Encoding UTF8Encod
  • 如何让CQRS适应项目? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我发现了一个新术语 名叫CQRS 命令查询职责分离 http martinfowler com bliki CQRS html其中指出 概念模型
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • 如何在.NET Core上直接调用F#编译器?

    UPD 我想直接从 NET Core SDK 调用 F 编译器 即 fsc 我了解 dotnet build co 但当我只需要编译一个简单的问题时 即 fsc file fs 就足够的情况下 我不想涉及它们 我尝试在 NET Core S

随机推荐

  • 为什么 apply() 返回错误的列类型?

    我最近开始使用 R 和apply 功能让我绊倒 我很感激这方面的帮助 is numeric iris Sepal Length returns TRUE is numeric iris Sepal Width returns TRUE is
  • 如何在 C# 中枚举网络共享和 Web 文件夹?

    Net为我们提供了一个FolderBrowserDialog控件来浏览文件夹 然而 这是一个模式对话框 我需要创建一个可以拖放到表单上的用户控件 因此 我一直在考虑创建自己的 我需要在其中获取所有本地驱动器 映射的网络驱动器 UNC 共享和
  • 使用 EaselJs 制作倒计时动画

    我正在尝试使用画架模拟倒计时动画 我有一个它应该是什么样子的例子 http jsfiddle net eguneys AeK28 但它看起来像一个黑客 有没有适当 更好 灵活的方法来做到这一点 换句话说 我如何定义一条路径 并用 easel
  • Pod 在 aws eks 中使用节点组角色而不是服务帐户

    我正在使用一个服务帐户 并通过 OIDC 为其分配了角色 我在 Pod 中打开 shell 并检查当前角色 但我的服务正在做同样的事情 但它使用节点角色 Java SDK 版本 aws java sdk core 1 11 505 Pod
  • 何时决定调用带括号和不带括号的 R 函数

    我正在学习R 为什么有时 R 中的函数会用括号调用 比如myfunction vs 有时它被称为没有myfunction 我如何知道何时使用括号跟注而不使用括号 我在 tidyverse 中看到很多没有括号的函数调用 Answer reco
  • PowerShell 窗口阻止关闭

    如果我显示 PowerShell 窗口 在 PowerShell 命令提示符处 它会阻止计算机关闭 IE 如果我打开 PowerShell 窗口 然后尝试关闭服务器 我会收到 结束程序 弹出窗口 提示 Windows 无法结束此程序 如果从
  • 如何连接到 Vault 服务器

    我想尝试一下vault 所以我配置了VAULT ADDR as echo VAULT ADDR http 127 0 0 1 8200 然后我在开发模式下启动了vault vault server dev 一切正常 我能够连接到服务器 然后
  • Pandas 的 read_excel 中逗号作为小数分隔符

    我有一个包含 119 个工作表的 Excel 文件 我想获取数据来绘制多个图表 问题在于数值以逗号作为小数点分隔符 我读到 与 read csv 不同 Pandas 中的 read excel 函数没有这个选项 我打算从某些选定的工作表中加
  • Django 1.8 和 Rest Framework 3.7 出现“导入错误:没有名为 urls 的模块”

    我正在使用 django 1 8 rest framework 3 7 7 python 2 7 12 urls py urlpatterns url r api core include core urls 核心 urls py urlp
  • 行号不显示?

    我发现我的程序存在一些问题 我使用 log4j 进行日志记录 但是 在日志文件中 所有行号都变成 对话模式如下 log4j appender file layout ConversionPattern d dd MM yyyy HH mm
  • Rcpp:将 C 数组作为 NumericMatrix 返回到 R

    include
  • IntelliJ IDEA 中创建了错误的 Manifest.mf .jar

    我正在尝试通过 IntelliJ IDEA 的 jar 工件将使用 OptaPlanner 6 0 1 库的项目打包到 jar 中 而不是包含标准的 manifest mf Manifest Version 1 0 Main Class a
  • CSS - 有两个切角的按钮[重复]

    这个问题在这里已经有答案了 大家好 我想创建一个
  • rgdal - 读取 ESRI 地理数据库 (gdb) 中的表

    我正在尝试使用 R 从 ESRI 地理数据库 gdb 读取没有几何图形的表 readOGR 抛出错误 因为没有定义几何图形 这是有意义的 library rgdal readOGR gSSURGO CO gdb mutext Error i
  • 如何创建 NSManagedObjectContext

    在 iPhone 的核心数据中 我在尝试将数据保存到NSManagedObjectContext 我相信我的问题都与我使用NSManagedObjectContext这是在多个线程中使用的 所以我想创建一个新的NSManagedObject
  • 我如何使用pyqt5中的QTextEdit显示html的所有样式(包括css的样式)

    Python 3 6 PYQT 5 12 1 我准备通过pyqt5来展示我需要的样式 并且我知道pyqt5中的QTextEdit可以很好地显示html代码 我有一些web开发经验 所以我决定使用html css来展示我的样式 但是 在 cs
  • 如何更改 TRichEdit 中某些字符的颜色? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我正在做一个 Delphi 7 项目 我必须让用户输入一个数字 向下的层 来构建圣诞树
  • 返回十六进制 UUID 作为 Django 模型 charfield 的默认值

    我尝试创建一个具有从 uuid4 生成的标识符的模型 但我想要的不是常规的 uuid 而是标识符具有十六进制 uuid 格式 不带 这是我尝试过的 class Model models Model identifier models Cha
  • 使用 SQL 搜索 DB2 进行分页的最快/最有效的方法

    现在我执行两个单独的 SQL 语句 其中一个执行SELECT COUNT 与搜索语句的标准基本相同 我不是最擅长做出这些陈述 有时有点慢 我想知道是否有更好的方法来做我所做的事情 可能只执行一条 SQL 语句并在 PHP 中执行更多工作 这
  • 为什么“密封”会影响 IDisposable 的实现?

    看完答案后here 我决定将我的课程标记为密封以简化I一次性执行 为什么sealed会影响IDisposable的实现 例如GC SuppressFinalize this 不需要调用 请解释发生了什么事 我需要能够向其他开发人员解释为什么