Implementing RAII in C #

I have an InfoPath form in which I need to conditionally disable OnChange events. Since it is not possible to bind event handlers after the form loads, I have to rely on a global counter that indicates whether the OnChange event should be executed. Inside each OnChange event, I check to see if SuppressEventsCount == 0 before performing any actions. To suppress events during the execution of a function, I simply set SuppressEventsCount ++ and - again, when the function exits. The biggest problem with this is that it is no exception. So I had a bright idea to wrap the SuppressEvents counter in a class that implements iDisposable

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

This works, but it's still not perfect, like a C ++ solution that doesn't require the use of the using directive at all.

Is there any way:

  • Launching a destructor or some function at the moment when the object goes out of scope, OR
  • Preventing SuppressEvents Object Initialization Outside of the "using" Directive
+6
source share
4 answers

With respect to question 2, it is possible to work around it by providing a different interface to code consumers. Instead of providing an open class that implements IDisposable , and hoping they wrap it in using , you can provide a static method that executes a function to execute in a “suppressed” context:

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

Consumers can then use this as follows:

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

Of course, you need to decide if this project is suitable, as this will lead to additional function calls, compiler-generated classes and closure, etc.

+2
source

No and no. using is the closest to RAII (more precisely, it's about releasing a resource that follows an RAII-idiom object that is being destroyed).

To more accurately answer your questions:

  • IDisposable (and by extension using ) was created precisely because in .NET there is no way to do this.
  • using is syntactic sugar that compiles as try / finally and only requires the object to be IDisposable , so you cannot distinguish between using and from within the using statement.
+6
source

To answer two questions:

  • No, no, the Garbage Collection in .NET is not deterministic in nature
  • No, you cannot, the using clause is converted to try / finally block type code, and in any case you cannot find that it is built from any of these two constructs, compared to the external one
0
source

If you can switch from C # to C ++ .NET (still 100% .NET if compiled with clr: safe), you can use msclr :: auto_handle, which acts just like a smart pointer such as auto_ptr etc.

What he really does behind the scenes in IL is a bunch of try / fault commands, but it is completely invisible to the developer and the user. The whole process is just better IMO.

0
source

Source: https://habr.com/ru/post/912206/


All Articles