简体   繁体   中英

Custom Compound statements in c#

I would like to write my own custom compound statements that have a similar mechanism to using and lock mechanisms where they have code injected at the beginning and end of the statement block before compilation.

I have tried searching for questions who may have asked similar questions but I could not properly figure out what this kind of "code scoping" is called, other than the documentation saying these are compound statements.

Im aware that "lock" and "using" are keywords. I dont want to have my own keywords as I know this is not possible.

Im not sure if this is possible in c# for example:

Rather than doing:

StartContext(8);
//make method calls
EndContext();

This could be reduced down to:

DoSomethingInContext(8) {
    //make method calls
}

Ofcourse this does not have to be just a single one line call. The start and ends of encapuslated code could be multiple lines of code thats is inserted by the custom compound statement.

You can rewrite your code just slightly:

DoSomethingInContext(8, () => {
    // make method calls
});

The signature for your method would be something like this:

public void DoSomethingInContext(int contextId, Action contextBoundAction)
{
    // start/open/enter context
    try
    {
        contextBoundAction();
    }
    finally
    {
        // stop/close/exit context
    }
}

One thing to be aware of, since there is an alternative answer here that uses IDisposable , is that this delegate-based syntax can make intellisense in various (older) versions of Visual Studio and ReSharper get a little wonky. Sometimes it tries to help you fill out the parameter to DoSomethingInContext when you really want it to help you fill out parameters in method calls inside the delegate. This is also true for other IDEs such as older Xamarin Studios, which had severe performance problems regarding nested delegates (if you start nesting these context-bound things).

I wouldn't change my programming style because of this, but be aware of it.

If you don't mind a minimal amount of additional code, you can re-use the using statement. Simply put your wrapper code in the constructor and Dispose method, eg:

public class MyWrapper: IDisposable
{
    int _id;

    public MyWrapper(int id)
    {
        _id = id;
        Debug.WriteLine("Begin " + _id);
    }

    public void Dispose()
    {
        Debug.WriteLine("End " + _id);
    }
}

Usage:

using(new MyWrapper(id))
{
    Debug.WriteLine("Middle " + id);
}

Demo on DotNetFiddle


I've used this method to wrap methods that need to be used together, even if something goes wrong (eg the Push and Pop methods of DrawingContext ) - saves you a lot of finally blocks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM