Bad practice? Non-canon usage of c#'s using statement

后端 未结 6 1766
广开言路
广开言路 2021-01-01 16:36

C# has the using statement, specifically for IDisposable objects. Presumably, any object specified in the using statement will hold some sort of re

相关标签:
6条回答
  • 2021-01-01 16:51

    Just because you can (or because Phil Haack says it's okay), doesn't mean you should.

    The basic rule of thumb: if I can read your code and understand what it's doing and what your intent was, then it's acceptable. If, on the other hand, you need to explain what you did, or why you did it, it's probably going to trip up junior developers maintaining the code.

    There are many other patterns that can accomplish this with better encapsulation.

    The bottom line: this "technique" buys you nothing and only acts to confuse other developers.

    0 讨论(0)
  • 2021-01-01 16:56

    I recommend against it; my belief is that code is to effectively communicate with the maintainer of the code, not the compiler, and should be written with the maintainer's comprehension in mind. I try to use "using" only to dispose of a resource, typically an unmanaged resource.

    I am in a minority. Most people it seems use "using" as a general purpose "I want some cleanup code to run even if an exception is thrown" mechanism.

    I dislike this because (1) we already have a mechanism for that, called "try-finally", (2) it uses a feature for a purpose it was not intended for, and (3) if the call to the cleanup code is important, then why isn't it visible at the point where it is called? If it is important then I want to be able to see it.

    0 讨论(0)
  • 2021-01-01 16:56

    It's a common pattern, but personally, I believe that there's no excuse to abuse IDisposable like that when you can achieve the same effect in a much more obvious way with anonymous delegates and/or lambdas; i.e.:

    blitter.BlitOperation(delegate
    {
       // your code
    });
    
    0 讨论(0)
  • 2021-01-01 17:04

    I think you should use IDisposable for what it's intended for, and nothing else. That is, if maintainability matters to you.

    0 讨论(0)
  • 2021-01-01 17:10

    I'd say it's acceptable - in fact, I've used it in some projects where I wanted to have an action triggered at the end of a specific code block.

    Wes Deyer used it in his LINQ to ASCII Art program, he called it action disposable (Wes works on the C# compiler team - I'd trust his judgment :D):

    http://blogs.msdn.com/wesdyer/archive/2007/02/23/linq-to-ascii-art.aspx

    class ActionDisposable: IDisposable
    {
        Action action;
    
        public ActionDisposable(Action action)
        {
            this.action = action;
        }
    
        #region IDisposable Members
    
        public void Dispose()
        {
            this.action();
        }
    
        #endregion
    }
    

    Now you can return that from a function, and do something like this:

    using(ExtendedConsoleWriter.Indent())
    {
         ExtendedConsoleWriter.Write("This is more indented");
    }
    
    ExtendedConsoleWriter.Write("This is less indented");
    
    0 讨论(0)
  • 2021-01-01 17:13

    This is a perfectly acceptable practice. These are called Factored Types, and the Framework Design Guidelines recommends doing just this.

    Basically, if the type wraps an operation with a specific lifetime, using IDisposable and the using statement becomes an appropriate thing to consider.

    I actually blogged about this specific topic here, as well.

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