Creating a dictionary with void functions

Asked

Viewed 115 times

4

I am for fun to develop a TCP server in C# that performs functions depending on the message that the connected client sends you, for now, I only managed to do what I want with functions that return strings, for this I have the following:

A dictionary that stores the string the message the user is supposed to send to the server so that the function he wants and the function in question is executed:

private Dictionary<string, Func<string>> stringFunctions = new Dictionary<string, Func<string>>();

A function that looks for the function the customer wants:

private string CheckCommands() {
    for(int i = 0; i < stringFunctions.Count; i++)
        if(stringFunctions.ContainsKey(rcvString))
            return stringFunctions[rcvString].Invoke();
    return "";
}

Realisation of demand within the communication loop with the customer:

string commandAnswer = CheckCommands();
if(commandAnswer != "") {
    netStream.Write(Encoding.ASCII.GetBytes(commandAnswer), 0, Encoding.ASCII.GetBytes(commandAnswer).Length);
    Console.WriteLine("Sent: {0}", commandAnswer);
} else {
    netStream.Write(Encoding.ASCII.GetBytes("Could not find that command in our database"), 0, Encoding.ASCII.GetBytes("Could not find that command in our database").Length);
}

How do I put the function in the dictionary:

myFunctions.Add("test", new Func<string>(Test));

This all I presented works, but I wanted now to be able to use the same method but for void functions, is there any way similar to what I try to do? I still can’t get there.

1 answer

3


Using the same method, if I understood it, is not possible because the method you wrote expects to work with a function that returns a string.

In fact your dictionary only accepts functions with the same signature, that is, without parameters and with the return of type string. To keep the same line you would have to use other dictionaries with other signatures, for example to do whatever you want:

private Dictionary<string, Action>> voidFunctions = new Dictionary<string, Action>();

And then a method that analyzes and calls the function with no return.

Documentation.

If you really want to put everything in the same dictionary you have to do something like this:

private Dictionary<string, dynamic> functions = new Dictionary<string, dynamic>();

or

private Dictionary<string, object>> functions = new Dictionary<string, object>();

I put in the Github for future reference.

And your method to execute the function should use as return the dynamic or object also.

Except that there is worth putting anything there and to stay robust would have to control what adds to make sure it is a function and at the time of calling also have to route properly, IE, It is much more complicated.

There are countless other ways to do it, but you have to think about several aspects, the decision is not simple, you can’t tell what is good without knowing details. And none will be simple, unless you do it in a naive, fragile, even insecure way.

To give an example, you can use the system of scripts to call the function. I’m not a big fan of it, it may be pretty unsafe, but it’s to illustrate that it has options and each has its drawbacks.

The use of reflection may be the most suitable way in many cases. In some cases the use of a code generator can simplify a lot of things.

For some cases, but not all, it could have an extra indirect that linearizes the use of all functions.

  • Yes I know that my dictionary only accepts string functions, I just wanted to know how to change so that this other kind of functions as explained later. By the way, in your code snippets you continue to call a dictionary of type <string, Func<string>>. Anyway thanks, it helped a lot!

  • Yeah, I forgot to change in both places.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.