- Home /
How to feed several (0-n) functions into another function
Hello, I've got a question about how I can feed several functions (with arguments) into another function. I assume this has to work via delegates somehow, but I'm not sure how.
The basic idea is I want to have an unmark function that I can feed other functions such as "Remove buildings" or "build buildings" or just null (in case that I don't actually want to do anything than to remove all my markings).
Currently it looks like this:
if (tool == Tool.Remove)
{
for (int x = xMin; x <= xMax; x++)
{
for (int z = zMin; z <= zMax; z++)
{
Mark(x, z, 0);
Destroy(gameObjects[x, markingOld.y, z]);
fieldInfos[x, markingOld.y, z].construction = Construction.Empty;
}
}
}
What I want to do is to feed the
Destroy(gameObjects[x, markingOld.y, z]);
fieldInfos[x, markingOld.y, z].construction = Construction.Empty;
into a function like this:
private void UnmarkAll(Delegate function)
{
for (int x = xMin; x <= xMax; x++)
{
for (int z = zMin; z <= zMax; z++)
{
Mark(x, z, 0);
//Execute everything I fed into the argument
function();
}
}
}
So I don't need to spam the for loops everywhere and keep my code somewhat compact.
I'd also like the option to feed a null into the "UnmarkAll" function. Or just one function. Is there a way to do this?
Answer by TreyH · Oct 02, 2018 at 08:13 PM
If you're comfortable with a fairly unsightly syntax, you can use a lambda function cast as System.Action
:
edit: added arguments, didn't see that you needed them.
private void UnmarkAll(System.Action<int, int> action)
{
if (tool == Tool.Remove)
{
for (int x = xMin; x <= xMax; x++)
{
for (int z = zMin; z <= zMax; z++)
{
Mark(x, z, 0);
action(x, z);
}
}
}
}
You'd then call it like this:
this.UnmarkAll((x, z)=>{
Destroy(gameObjects[x, markingOld.y, z]);
fieldInfos[x, markingOld.y, z].construction = Construction.Empty;
});
Thank you very much. This works perfectly.
I just don't understand how. From the way the syntax looks the (x,z)
is assigned to the functions. But what actually seems to happen is that the functions are fed into the UnmarkAll
function and are assigned the arguments x and z from the UnmarkAll
function.
These lambdas confuse me...
Actually does the (x, z)
actually matter when the function is called or could I put some other variable name in there? Like:
this.UnmarkAll((var1, var2)=>{
Destroy(gameObjects[var1, markingOld.y, var2]);
fieldInfos[var1, markingOld.y, var2].construction = Construction.Empty;
});
Ins$$anonymous$$d of
this.UnmarkAll((x, z)=>{
Destroy(gameObjects[x, markingOld.y, z]);
fieldInfos[x, markingOld.y, z].construction = Construction.Empty;
});
And it'd still work? I don't think I really understand what this is actually doing.
Try it out for yourself! These are also called "Anonymous Functions" as you don't give them a name, if that's less esoteric than "Lambda".
The names do not matter when you actually make the lambda function itself because the compiler already knows what variable types to expect (from the UnmarkAll definition). In that definition, we told C# that it was going to receive an Action (which can be a named or anonymous function that returns nothing) using two integer arguments. So when we actually call UnmarkAll, it is assu$$anonymous$$g that your lambda arguments are integers.
It might seem closer to python than a strongly typed language like C#, but types are being enforced here. :-)