Implementing RAII in C#

前端 未结 4 1517
一整个雨季
一整个雨季 2021-01-18 00:47

I have an InfoPath form which I need to conditionally disable it\'s OnChange events. Since it\'s not possible to bind the event handlers after the form has loaded, I\'m forc

相关标签:
4条回答
  • 2021-01-18 01:04

    To answer your two questions:

    1. No, there is not, Garbage Collection in .NET is not deterministic in nature
    2. No, you can not, the using clause gets translated into a try/finally block type of code, and in any case you cannot detect that it is constructed from any of those two constructs, compared to outside
    0 讨论(0)
  • 2021-01-18 01:05

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

    What it really does behind the scene in IL is a bunch of try/fault commands but this is all completely invisible to the developer and user. The whole process is simply better IMO.

    0 讨论(0)
  • 2021-01-18 01:12

    No and no. using is the closest you can get to RAII (more accurately, we are talking about the resource release that follows a RAII-idiom object being destructed).

    To answer your points more directly:

    1. IDisposable (and by extension using) was created exactly because there is no way to do that in .NET.
    2. using is syntactic sugar that gets compiled as try/finally and only requires that the object is IDisposable, so you cannot distinguish between usage inside a using statement and out of it.
    0 讨论(0)
  • 2021-01-18 01:24

    In relation to question 2, it might be possible to get around it by providing a different interface to consumers of the code. Instead of providing a public class that implements IDisposable, and hoping they wrap it in a using, you could provide a static method that takes 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 {
            ...
        }
    }
    

    Then consumers can use this as follows:

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

    Of course, you have to work out whether this design is appropriate, as this will result in extra function calls, compiler generated classes and closures etc.

    0 讨论(0)
提交回复
热议问题