Search code examples
c#first-class-functions

"Using generic type 'Func<TResult>' requires 1 type arguments" issue when defining a delegate function type with more than 4 arguments


I receiving the following error: "Using generic type 'Func<TResult>' requires 1 type arguments". It occurs when I attempt to define a dictionary which maps strings to delegate functions.

The dictionary looks like this:

Dictionary<string, string> builtInFunctions = new Dictionary<string, Func<Expression, Dictionary<string, string>, Dictionary<string, Value>, Dictionary<string, Token>, Dictionary<string, Cube>, Result>>()
{
    {"ToString", ToString}
};

Result ToString(
    Expression expression,
    Dictionary<string, string> env, 
    Dictionary<string, Value> store, 
    ref Dictionary<string, Token> tokenEnv, 
    ref Dictionary<string, Cube> cubeEnv
) {
    // implemented ToString function
}

And the error is occurring on this partof the code:

Func<Expression, Dictionary<string, string>, Dictionary<string, Value>, Dictionary<string, Token>, Dictionary<string, Cube>, Result>

And it still appears if I use different simpler types for it, for instance:

Func<int, int, int, int, int, int>

Can delegate functions only take 4 arguments, or is there a way around this?


Solution

  • Your ToString function mustn't have ref parameters.

    They are not defined in your Func and they can't be.

    Look at this question for more insight.

    You might have error in your code, because declaring a Func with four or five arguments shouldn't be a problem.

    This code works perfectly fine with me:

    using System;
    using System.Collections.Generic;
    
    public class Expression{}
    public class Value{}
    public class Token{}
    public class Cube{}
    public class Result{
        public int result = 11;
    }
    
    namespace MyNameSpace{
        using MyGenericFunc = Func<Expression, Dictionary<string, string>, Dictionary<string, Value>, Dictionary<string, Token>, Dictionary<string, Cube>, Result>;
    
    
        public class Program
        {
            public static void Main()
            {
                Expression expression = new Expression();
                Dictionary<string, string> env = new Dictionary<string, string>(); 
                Dictionary<string, Value> store = new Dictionary<string, Value>();
                Dictionary<string, Token> tokenEnv = new Dictionary<string, Token>();
                Dictionary<string, Cube> cubeEnv = new Dictionary<string, Cube>();
    
                // normal call
                Console.WriteLine("When calling the method directly: " + ToStringFunc(expression, env, store, tokenEnv, cubeEnv).result);
    
                // call via func and dictionary
                MyGenericFunc retrievedFunc;
                builtInFunctions.TryGetValue("ToString", out retrievedFunc);
                Console.WriteLine("When calling the method retrieved from dictionary: " + retrievedFunc.Invoke(expression, env, store, tokenEnv, cubeEnv).result);
            }
    
            static Dictionary<string, MyGenericFunc> builtInFunctions = new Dictionary<string, MyGenericFunc>()
            {
                {"ToString", ToStringFunc}
            };
    
            static Result ToStringFunc(
                Expression expression,
                Dictionary<string, string> env, 
                Dictionary<string, Value> store, 
                Dictionary<string, Token> tokenEnv, 
                Dictionary<string, Cube> cubeEnv
            ) {
                return new Result();
            }
        }
    }
    

    You can test it quickly here.