Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension methods on Action/Func for regular method

I am a programmer, and I am lazy. Currently I am working with some OpenAL wrappers in C#. Every time I call an OpenAL method, I have to request the error from OpenAL using GetError and if there is one, I throw an exception. It didn't take long until I added a static helper class containing the following function:

    public static void Check()
    {
        ALError error;
        if ((error = AL.GetError()) != ALError.NoError)
            throw new InvalidOperationException(AL.GetErrorString(error));
    }

This worked for a while, but I wanted more. So, after a while, I came up with the following methods:

    public static void Call(Action function)
    {
        function();
        ALHelper.Check();
    }

    public static void Call<TParameter>(Action<TParameter> function, TParameter parameter)
    {
        function(parameter);
        ALHelper.Check();
    }

    public static TReturn Eval<TReturn>(Func<TReturn> function)
    {
        var val = function();
        ALHelper.Check();
        return val;
    }

    public static TReturn Eval<TParameter, TReturn>(Func<TParameter, TReturn> function, TParameter parameter)
    {
        var val = function(parameter);
        ALHelper.Check();
        return val;
    }

This worked great, but I was still not happy with how exactly the code looked when used, so I decided to take it one step further: I turned the above methods into extension methods. As I knew I could pass methods as the Action and Func parameters, I thought it would work as well for extension methods, turning the ugly handles = ALHelper.Eval(AL.GenBuffers, amount) into a more elegant handles = AL.GenBuffers.Eval(amount).

Sadly, I was welcomed with an exception once I started using this: Expression denotes a method group', where avariable', value' ortype' was expected.

Somewhat saddened that this doesn't work, I actually got curious as to why this wouldn't work. What exactly is the reason you can pass a method as Action or Func, but using extension methods doesn't work? Is this a limitation of the Mono compiler I am using (.NET 4.0) I am using, or is there something else going on inside?

like image 424
Tom Avatar asked Oct 18 '14 12:10

Tom


1 Answers

I think you misunderstand the concept of extension method.They are used to extend types. In this case AL.GenBuffers is a method, it isn't a Func or Action.It's signature may be compatible with them but it doesn't mean it is a func or action or any other kind of delegate type. In your example you are able to pass it like AL.GenBuffers because of the method group conversions. When compiler see the method signature is compatible it converts it to delegate type.

like image 144
Selman Genç Avatar answered Oct 04 '22 18:10

Selman Genç