0

In my specific use-case I have a couple of places that use Interlocked.Increment and Interlocked.Decrement interchangeably and so I wanted to consolidated the logic into a single method, and pass the correct method to be invoked, as argument:

if (Interlocked.Increment(ref x) == something)
{
    DoThis();
}
else
{
    DoThat();
}

And another place where I do:

if (Interlocked.Decrement(ref x) == something)
{
    DoThis();
}
else
{
    DoThat();
}

And the idea is to consolidate into:

void Foo(Action<ref int> interlockedOp)
{
    if (interlockedOp(ref x) == something)
    {
        DoThis();
    }
    else
    {
        DoThat();
    }    
}

But the Action<ref int> part doesn't compile.

Is there any other way to achieve this?

alexyav
  • 97
  • 1
  • 5
  • Not with a built-in, you'd have to create your own delegate type, see: http://stackoverflow.com/questions/2030303/delegate-for-an-action-ref-t1-t2 – UnholySheep Apr 30 '17 at 11:31

1 Answers1

2

Even if Action<ref int> compiled, it wouldn't work. Increment/Decrement return a value. You're even using the return value. Func<ref int, int>, if it compiled, would do it, but you still cannot use ref in that context.

With a custom delegate type, it's easy.

delegate int InterlockedOp(ref int location);
  • Yes, I used `Action` by mistake, should have been `Func`. And thank you for showing how to do this with a delegate. Now off to learn about the differences between using a delegate and `Func`/`Action` :) – alexyav Apr 30 '17 at 12:23