0

I am getting a compile error when I attempt to add a method/function to a Dictionary <string, Delegate>. Can you tell me how I can add my method geometryContentParser() to the dictionary? Maybe I need to change the Dictionary value type to Event instead of Delegate?

Compile Error:

Cannot convert method group 'geometryContentParser' to non-delegate type 'System.Delegate'. Consider using parentheses to invoke the method

Heres my simple code:

public class FileParser 
{
    private Dictionary<string, Delegate>    customParsingCallbacks  = new Dictionary<string, Delegate>();

    public FileParser() 
    {
        customParsingCallbacks["points"] = geometryContentParser; // compile error: "Cannot convert method group `geometryContentParser' to non-delegate type `System.Delegate'. Consider using parentheses to invoke the method"
    }

    private bool geometryContentParser(string formattedLine) {
        // Post: Returns True if this custom content parser is still running (needs to look at the next line) else false for completion

        if (formattedLine.Contains("}")) {
            return false;
        }

        return true;
    }
}

Also which is the correct invocation method?

customParsingCallbacks["points"]("");
// OR
customParsingCallbacks["points"].DynamicInvoke("");
sazr
  • 24,984
  • 66
  • 194
  • 362
  • Just cast it to `Delegate`. There's no default conversion. – siride Jul 06 '14 at 05:47
  • But really, you should define your delegate type to take a specific set of arguments and return a specific value, so you can use some version of `Func<>` or `Action<>` instead of using the most generic type possible (`Delegate`). What arguments will be passed to these methods? What will be done with the return value? – siride Jul 06 '14 at 05:52
  • For the second part (invoke vs DynamicInvoke), see this question: http://stackoverflow.com/questions/12858340/difference-between-invoke-and-dynamicinvoke – qbik Jul 06 '14 at 05:56
  • Check my answer with Func<> instead of delegate. – Ajay Kelkar Jul 06 '14 at 06:03

2 Answers2

2

Instead of using delegates use Func , see below code

public class FileParser
{
    private Dictionary<string, Func<string, bool>> customParsingCallbacks = new Dictionary<string, Func<string, bool>>();

    public FileParser()
    {
        customParsingCallbacks["points"] = new Func<string, bool>((s) => { 
                                                 return geometryContentParser(s);
                                                                    }); 
    }

    private bool geometryContentParser(string formattedLine)
    {
        // Post: Returns True if this custom content parser is still running (needs to look at the next line) else false for completion

        if (formattedLine.Contains("}"))
        {
            return false;
        }

        return true;
    }
}

To call , do like this

bool result = customParsingCallbacks["points"]("somestring");
Ajay Kelkar
  • 4,591
  • 4
  • 30
  • 29
2

I'm still pretty novice in C#, so probably this answer is lightning years late, but I can see the benefit of using Delegate instead of Func. Using Delegate will provide freedom on the function's return variable type. Using Func will force return variable type consistent for all members in the dictionary. So to use delegate, it will be something like this:

public class FileParser
{
    public static Dictionary<string, Delegate> customParsingCallbacks  = new Dictionary<string, Delegate>();

    delegate string delegate1(int x, int y);
    delegate int delegate2(string str1);

    static FileParser()
    {
        customParsingCallbacks["points"] = new delegate1(geometryContentParser);
        customParsingCallbacks["period"] = new delegate2(function2);
    } 

    private bool string geometryContentParser(int x, int y)
    {
        if (formattedLine.Contains("}"))
        {
            return false;
        }

        return true;
    }   

    private static int function2(string str1)
    {
        int result = 1;
        return result;
    }
}

And to use the function dictionary:

var output = FileParser.customParsingCallbacks["points"].DynamicInvoke(1,1);
TRizal
  • 21
  • 2