Search code examples
c#compiler-errorslambdacompiler-bug

'Delegate 'System.Action' does not take 0 arguments.' Is this a C# compiler bug (lambdas + two projects)?


Consider the code below. Looks like perfectly valid C# code right?

//Project B
using System;
public delegate void ActionSurrogate(Action addEvent);
//public delegate void ActionSurrogate2();
// Using ActionSurrogate2 instead of System.Action results in the same error
// Using a dummy parameter (Action<double, int>) results in the same error

// Project A
public static class Class1 {
    public static void ThisWontCompile() {
        ActionSurrogate b = (a) =>
                            {
                                a(); // Error given here
                            };
    }
}

I get a compiler error 'Delegate 'Action' does not take 0 arguments.' at the indicated position using the (Microsoft) C# 4.0 compiler. Note that you have to declare ActionSurrogate in a different project for this error to manifest.

It gets more interesting:

// Project A, File 1
public static class Class1 {
    public static void ThisWontCompile() {
        ActionSurrogate b = (a) => { a(); /* Error given here */ };
        ActionSurrogate c = (a) => { a(); /* Error given here too */ };
        Action d = () => { };
        ActionSurrogate c = (a) => { a(); /* No error is given here */ };
    }
}

Did I stumble upon a C# compiler bug here?

Note that this is a pretty annoying bug for someone who likes using lambdas a lot and is trying to create a data structures library for future use... (me)

EDIT: removed erronous case.

I copied and stripped my original project down to the minimum to make this happen. This is literally all the code in my new project.


Solution

  • This probably is a problem with type inference, apperently the compiler infers a as an Action<T> instead of Action (it might think a is ActionSurrogate, which would fit the Action<Action>> signature). Try specifying the type of a explicitly:

        ActionSurrogate b = (Action a) =>
                            {
                                a();
                            };
    

    If this is not the case - might check around your project for any self defined Action delegates taking one parameter.