Csharp/C#教程:在C#中实现RAII分享


在C#中实现RAII

我有一个InfoPath表单,我需要有条件地禁用它的OnChange事件。 由于在表单加载后无法绑定事件处理程序,因此我不得不依赖一个全局计数器来指示是否应该执行OnChange事件。 在每个OnChange事件中,我在执行任何操作之前检查SuppressEventsCount == 0。 为了在执行某个函数或其他函数期间抑制事件,我只需设置SuppressEventsCount ++,并且 – 当函数退出时再次。 这样做的最大问题是它不是例外的安全。 所以我有一个聪明的主意将SuppressEvents计数器包装在一个实现iDisposable的类中

using(SuppressEvents s = new SuppressEvents()){ // OnChange events fired here are ignored } // OnChange events enabled again 

这是有效的,但它仍然不如c ++解决方案那么理想,它根本不需要使用“using”指令。

有没有办法:

  1. 在对象超出范围时触发析构函数或某些函数,或者
  2. 防止SuppressEvents对象完全在“using”指令之外进行初始化

关于问题2,可以通过为代码的消费者提供不同的接口来绕过它。 而不是提供实现IDisposable的公共类,并希望它们将它包装在一个using ,您可以提供一个静态方法,该方法将函数在“被抑制”的上下文中执行:

 public static class EventSuppressor { public void Suppress(Action action) { using (var s = new SuppressActions()) { action(); } } private class SuppressActions : IDisposable { ... } } 

然后消费者可以使用如下:

 EventSuppressor.Suppress(() => { // OnChange events fired here are ignored }) // OnChange events enabled again 

当然,您必须确定此设计是否合适,因为这将导致额外的函数调用,编译器生成的类和闭包等。

不,不。 using是最接近RAII的(更准确地说,我们正在讨论在被破坏的RAII-idiom对象之后的资源释放)。

更直接地回答您的观点:

  1. IDisposable (以及扩展using )的创建完全是因为在.NET中无法做到这一点。
  2. using是语法糖,它被编译为try / finally并且只要求对象是IDisposable ,因此你无法区分using语句中的用法和out。

回答你的两个问题:

  1. 不,没有,.NET中的垃圾收集本质上不具有确定性
  2. 不,您不能, using子句被转换为try / finally块类型的代码,并且无论如何您无法检测到它是从这两个构造中的任何一个构造的,与外部相比

如果你可以从C#转移到C ++ .NET(如果使用clr:safe编译,仍然是100%.NET),那么你可以使用msclr :: auto_handle,它就像一个智能指针,如auto_ptr等……

IL中场景背后的真正原因是一堆try / fault命令,但这对于开发人员和用户来说都是完全不可见的。 整个过程简直就是更好的IMO。

上述就是C#学习教程:在C#中实现RAII分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/955897.html

(0)
上一篇 2021年11月21日
下一篇 2021年11月21日

精彩推荐