7

I have many methods similar to this:

 void GetColorSky(out float r, out float g, out float b)
 void GetColorGround(out float r, out float g, out float b)

"Similar" meaning they have the exact same method header excluding the method name. I also have several "colourPicker" controls, that accept R, G, B values.

I am trying to create a method that accepts a method as one of it's parameters, like so:

UpdateColourPicker(ColorPicker cp, CustomMethod cMethod)

and call it as follows:

UpdateColourPicker(cpSky, GetColorSky)
UpdateColourPicker(cpGround, GetColorGround)

What is the correct syntax for out and Action together? I've looked at this question but I still haven't managed.

Thanks!

Community
  • 1
  • 1
David
  • 15,652
  • 26
  • 115
  • 156
  • As a general guideline, it would be better for your functions to return value rather than using out params as they makes functions non-composable – Ankur Jun 12 '12 at 12:35
  • What is wrong with just declaring those methods like `Color GetColorSky()`? All those out parameters seem quite unnecessary to me. – Botz3000 Jun 12 '12 at 12:37
  • @Ankur I have no choice. The functions aren't coming from c# but from an external DLL so I have to use references. Thanks for the advice though. – David Jun 12 '12 at 12:43
  • possible duplicate of [Func with out parameter](http://stackoverflow.com/questions/1283127/funct-with-out-parameter) – nawfal Apr 03 '13 at 06:20

2 Answers2

5

Taking cue from that linked answer, this will work:

public delegate void GetColorDel(out float r, out float g, out float b);

void UpdateColourPicker(ColorPicker cp, GetColorDel cMethod) { }

UpdateColourPicker(cpSky, GetColorSky);
UpdateColourPicker(cpGround, GetColorGround);

Unfortunately, as stated in the answer to the question you link, Action and Func do not work with out and ref. This is simply because Action and Func are just delegate definitions stated (quite a few times to offer different overloads) with generics in the BCL. Adding ref and out variants would quickly cause re-definition compiler errors.

The full sample:

class Program
{        
    public delegate void GetColorDel(out float r, out float g, out float b);

    static void Main(string[] args)
    {
        UpdateColourPicker(null, GetColorSky);
        UpdateColourPicker(null, GetColorGround);

        Console.Read();
    }

    static void GetColorSky(out float r, out float g, out float b) 
    {
        r = g = b = 0f;
        Console.WriteLine("sky"); 
    }

    static void GetColorGround(out float r, out float g, out float b) 
    {
        r = g = b = 0f;
        Console.WriteLine("ground"); 
    }

    static void UpdateColourPicker(object cp, GetColorDel cMethod) 
    {
        float r, g, b;
        cMethod(out r, out g, out b);
    }
}
Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • He wants to know how to use one of the `Action` delegates. – leppie Jun 12 '12 at 12:25
  • @leppie: You already told the OP that `out` isn't supported with generic types, so you clearly know that you can't use `out` with `Action<>` delegates. I'm not sure what your comment is getting at. – Gabe Jun 12 '12 at 12:26
  • @leppie I know, and that is answered in his own linked question. I'll amend to be clearer. – Adam Houldsworth Jun 12 '12 at 12:26
  • Thanks for a comprehensive answer. I couldn't get the syntax right. – David Jun 12 '12 at 12:30
  • @David This covers the `float` variant of the method, if you want to use generics then [@jeroenh's answer](http://stackoverflow.com/a/10996698/358221) is the syntax you need. Unforunately generics and arithmetic-styled method don't usually gel very well as standard operators are not supported via generic constraints (`+`, `-`, `*`, etc), so I'd see little benefit in worrying about the generics for now. – Adam Houldsworth Jun 12 '12 at 12:31
2

If you want to define a generic delegate with out parameters, it should be done like this:

delegate void ActionWithOutparameter<T>(out T x);
delegate void ActionWithOutparameter<T1, T2>(out T1 x, out T2 y);
// ...

Clearly the Action and Func delegates in the BCL do not match this signature.

jeroenh
  • 26,362
  • 10
  • 73
  • 104