40

I have a method with an out parameter, and I'd like to point an Action or Func (or other kind of delegate) at it.

This works fine:

static void Func(int a, int b) { }
Action<int,int> action = Func;

However this doesn't

static void OutFunc(out int a, out int b) { a = b = 0; }
Action<out int, out int> action = OutFunc; // loads of compile errors

This is probably a duplicate, but searching for 'out parameter' isn't particularly fruitful.

Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
  • possible duplicate of [Func with out parameter](http://stackoverflow.com/questions/1283127/funct-with-out-parameter) – nawfal Apr 03 '13 at 06:19

2 Answers2

62

Action and Func specifically do not take out or ref parameters. However, they are just delegates.

You can make a custom delegate type that does take an out parameter, and use it, though.

For example, the following works:

class Program
{
    static void OutFunc(out int a, out int b) { a = b = 0; }

    public delegate void OutAction<T1,T2>(out T1 a, out T2 b);

    static void Main(string[] args)
    {
        OutAction<int, int> action = OutFunc;
        int a = 3, b = 5;
        Console.WriteLine("{0}/{1}",a,b);
        action(out a, out b);
        Console.WriteLine("{0}/{1}", a, b);
        Console.ReadKey();
    }
}

This prints out:

3/5
0/0
Chad
  • 7,279
  • 2
  • 24
  • 34
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • In the above example the type `OutAction` is nested inside the type `Program`. This is perfectly fine. But it is also possible to have non-nested delegate type, i.e. `OutAction` could be a direct member of the `namespace`. – Jeppe Stig Nielsen Jun 24 '15 at 11:51
  • Adding to this answer, passing the delegate as parameter could use something like `DoSomething(OutAction callback) { T1 first = 'someValue'; T2 second = 'someValue'; callback(out first, out second); }` – Quad Coders Sep 08 '21 at 15:16
3

No, not with the builtin delegates. out and ref are special qualifiers and the delegate has to be setup with them explicitly since they are completely different calling styles.

However, if you defined your own delegate, you can do this:

delegate void OutAction<T1, T2>(out T1 a, out T2 b);
Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222