TomHashNL
TomHashNL

Reputation: 108

Why are code blocks hierarchical? Extra points: Beautiful way to write my code block

Let's say I want to use 2 classes which implement the IDispose pattern. One of the classes uses the other for instantiation but is not needed afterwards. When stacking "using" keywords this will result in (for example) a locked file for the duration of using the font. I want the file to be unlocked right after I'm done with it for "coding beauty" reasons.

Have a look at the following "tag-like" system.

using1 (Stream stream = File.OpenRead("font.ttf"))
using2 (Font font = FontExtensions.FromStream(stream, 32))
ENDusing1
//use font here
ENDusing2

The hierarchical way, how code blocks are designed, impose a (beauty) limitation on the current handling of this. Ofcourse this can be solved by using try/finally blocks, but these aren't as neat.

Am I missing a fundamental design with using (lol?) nested IDisposable objects / Streams?

Please share your opinion on tag-code-blocks and the best way to solve this (coding beauty).

Upvotes: 3

Views: 176

Answers (2)

Lee
Lee

Reputation: 144136

You could create a utility method to create your object from a temporary resource:

public static T FromTempResource<T, TDisp>(Func<TDisp> dispFunc, Func<TDisp, T> createFunc) where TDisp : IDisposable
{
    using(TDisp d = dispFunc())
    {
        return createFunc(d);
    }
}

your example could then be:

using (Font font = FromTempResource(() => File.OpenRead("font.tt"), stream => FontExtensions.FromStream(stream, 32))
{

}

Upvotes: 2

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112402

You can nest the usings and at the same time close or even dispose the stream prematurely.

using (Stream stream = File.OpenRead("font.ttf")) {
    using (Font font = FontExtensions.FromStream(stream, 32)) {
        stream.Close(); // Or stream.Dispose();

        //use font here
    }
}

The FileStream class uses a flag internally to know whether it has been closed or disposed and ensures that this will not happen twice. The Dispose method just calls the Close method.

Upvotes: 9

Related Questions