TheGeneral
TheGeneral

Reputation: 81523

How do I create a method with a usage pattern like lock?

How could i create a method like lock in C#

I.e. the pattern for lock is

lock(inputParam)
{
   // code here
}

I want to create a similar method with a similar usage pattern that internally executes some code before and after code between the brackets,

SomeFunc(InputParam)
{
   // Do some stuff
}

Is lock a special case in C#, or are we able to achieve similar results with some sort of lambda / action dark magic?

Upvotes: 1

Views: 94

Answers (2)

Tim S.
Tim S.

Reputation: 56556

lock is only a little special: it is mentioned in the C# Specification, but is equivalent to code you could write (see §8.12 of the spec). You can do something vaguely similar:

void Main()
{
    SomeFunc(2, () => {
        //do stuff
    });
}
public void SomeFunc(int inputParam, Action body)
{
    //do before stuff
    body();
    // do after stuff
}

Such a pattern sounds unusual, however. I'd see if there's a better way to do what I want, before assuming this is a good approach.

Upvotes: 1

Jim Mischel
Jim Mischel

Reputation: 134035

No dark magic. What you want is try/finally:

DoSomething();
try
{
    // lots of stuff here
}
finally
{
    // do other stuff
}

I suppose you could write a method that does it for you:

void DoTryFinally(Action start, Action stuff, Action final)
{
    start();
    try
    {
        stuff();
    }
    finally
    {
        final();
    }
}

And to call it:

DoTryFinally(
    () => { /* start stuff here */ },
    () => { /* stuff here */ },
    () => { /* final stuff here */ });

I'd suggest the first way, though: try/finally is a common idiom in C#.

By the way, the code you posted:

lock (someObject)
{
    // do stuff
}

Is really just shorthand for what is essentially this:

Monitor.Enter(someObject);
try
{
    // do stuff
}
finally
{
    Monitor.Exit(someObject);
}

The compiler generates that when it compiles a lock statement.

There is no facility built in to the compiler that will let you do that with arbitrary functions. The Dispose pattern comes close, but it's not a general solution.

Upvotes: 3

Related Questions