# How to make a list containing both strings and functions in c#?

Whilst it doesn't neccesarily need to be a list, I just need a variable that I can index, and arrive at either a string or a function. I've tried using List and whilst this works for strings, when I try to store a function I get an error message along the lines of "cannot convert from void to object".

Does anyone know how this might be done?

• The only thing I can think of is two separate data structures. Have your list of strings - for functions just store the name, or an ID. Also store a map of strings to function references. When you get an element from the list, check the map for a value associated with it. If it exists, then you can de-reference the function and call it, otherwise do not. – Natalo77 May 22 '20 at 8:29
• The OOP by-the-book solution would be to create two classes, one encapsulating a string and one encapsulating a function. Then create either an abstract base-class or an interface and have both classes extend/implement it. You can now create a container for the base-class / interface. But details would depend on how that container is actually used in your game and what you do with the things you take out of it, so there is not enough detail to provide this answer. – Philipp May 22 '20 at 9:45

I am not sure for what you'll need this but this should work for you:

    private void test()
{
IList<object> list = new List<object>();
Func<string, string> anyFunction = AnyFunction;

Action voidFunction = AnyVoidFunction;

foreach (var item in list)
{
if (item is string)
{
Debug.WriteLine(item);
}
if (item is Func<string,string>)
{
var result = (item as Func<string, string>)("Call it");
Debug.WriteLine("Function result is: "+result);
}

if(item is Action)
{
//Call method
(item as Action)();
}
}

//as it is a list you can of course index it
var indexedItem = list[0];

}

private string AnyFunction(string inputString)
{
return "Anything "+ inputString;
}

private void AnyVoidFunction()
{
Debug.WriteLine("AnyVoidFunction called!");
}


The variable 'list' will hold the string "mystring", the function "AnyFunction" and the method "AnyVoidFunction".

Then the list is iterated. The output will be:

mystring
Function result is: Anything Call it
AnyVoidFunction called!


This will work with all the arrays, lists, dictionaries, stacks, queues and so on in C#.

btw.: As the focus of the question is not really game releated but more of a programming question: https://stackoverflow.com/ will be better to ask.

• You're probably right about this being more to do with coding, so I'll post there. Also I tried using this, but it gives the error "cannot convert from method group to object". If it helps I declared the function using "public void FunctionName() {}". Perhaps this means function is the wrong word? – ShootingSharkBOC May 22 '20 at 9:06
• @ShootingSharkBOC: I expanded the answer so you can see how it will work with 'void FunctionName() {}'. – Gener4tor May 22 '20 at 9:14
• That seems to work. Thanks – ShootingSharkBOC May 22 '20 at 9:23

Do the values need to be ordered in any way? If not this might work:

public class StringAndFunctionList
{
private List<string> _strings = new List<string>();
private List<Function> _functions = new List<Function>();

public dynamic this[int index]
{
get
{
if (index >= 0)
return _strings[index];
return _functions[-1-index];
}
}

//Adds a new value and returns its index
{
if(value is string)
{
return _strings.Count - 1;
}
else if(value is Function)
{
return -_functions.Count;
}
throw new ArgumentException();
}
}


Functions have negative indizes, strings have positive indizes.

• I likely should have clarified, they do need to be in numerical order. The idea is a function will go to the next index in the list each time it is called and if it finds a string it will print the string, and if it finds a function it will call the function. – ShootingSharkBOC May 22 '20 at 9:11
using System;
using System.Collections.Generic;

class StringOrFunction
{
public string String;
public Delegate Func;

public StringOrFunction(string str)
{
String = str;
}
public StringOrFunction(Delegate func)
{
IsFunc = true;
Func = func;
}
public static implicit operator StringOrFunction(string str)
{
return new StringOrFunction(str);
}
public static implicit operator StringOrFunction(Delegate func)
{
return new StringOrFunction(func);
}
}
class Program
{
static void Main(string[] args)
{
void world()
{
Console.Write("world");
}

var list = new List<StringOrFunction>
{
"Hello ",
(Action) (world),
(Action) (() => Console.WriteLine("!"))
};

foreach (var stringOrFunction in list)
{
if (stringOrFunction.IsFunc)
{
stringOrFunction.Func.DynamicInvoke();
}
else
{
Console.Write(stringOrFunction.String);
}
}
}
}