- Home /
How to shortcut a lambda expression through a function?
Hi, is there anyway to skip writing the lambda expression using a function. I'm trying to do a test where I can modify a referenced float through coroutine, using the System.Action with the lambda expression. I have two functions, an IEnumerator function, and a normal function to call the start coroutine with that IEnumerator function, and a float parameter in the second function, for a referencing a float in script or out, in-between the lambda expression.
Here's the example below.
IEnumerator FloatTestIE(System.Action<float> refFloat, float startFloat, float endFloat)
{
float fTimer = startFloat;
refFloat(startFloat);
while (fTimer < endFloat)
{
fTimer += 1 * Time.deltaTime;
refFloat(fTimer);
yield return null;
}
refFloat(endFloat);
}
void FloatTest(float refFloat, float startFloat, float endFloat)
{
StartCoroutine(FloatTestIE((float f) => refFloat = f, startFloat, endFloat));
}
But for some reason it doesn't seem to work.
It works fine when I put it in lambda expression on the second function like this.
public float f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
FloatTest((float x) => f = x, 1, 10);
}
}
IEnumerator FloatTestIE(System.Action<float> refFloat, float startFloat, float endFloat)
{
float fTimer = startFloat;
refFloat(startFloat);
while (fTimer < endFloat)
{
fTimer += 1 * Time.deltaTime;
refFloat(fTimer);
yield return null;
}
refFloat(endFloat);
}
void FloatTest(System.Action<float> refFloat, float startFloat, float endFloat)
{
StartCoroutine(FloatTestIE(refFloat, startFloat, endFloat));
}
But I want it like this to keep it clean for me.
public float f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
FloatTest(f, 1, 10);
}
}
IEnumerator FloatTestIE(System.Action<float> refFloat, float startFloat, float endFloat)
{
float fTimer = startFloat;
refFloat(startFloat);
while (fTimer < endFloat)
{
fTimer += 1 * Time.deltaTime;
refFloat(fTimer);
yield return null;
}
refFloat(endFloat);
}
void FloatTest(float refFloat, float startFloat, float endFloat)
{
StartCoroutine(FloatTestIE((float f) => refFloat = f, startFloat, endFloat));
}
If there's any possible workarounds or if it's not possible at all, I'm not very familiar the lambda expression or the System.Action thing, since I just discovered it recently, let me know anyway what you all think, thank you.
Answer by andrew-lukasik · Aug 11, 2021 at 08:01 AM
void FloatTest(float refFloat, float startFloat, float endFloat)
{
StartCoroutine( FloatTestIE( (float f) => refFloat = f, startFloat, endFloat) );
}
Value types (structs) are passed by copy, not by reference. This is simple but very important to understand. Naming a struct refFloat
doesn't change that but confuse.
In other words: this refFloat
is just a float - it is not referencing that f
field in your class anymore here.
To fix this, pass the action (with it's original field references) and not the float value:
void FloatTest ( System.Action<float> action , float startFloat , float endFloat )
{
StartCoroutine( FloatTestIE( action, startFloat, endFloat) );
}
l also tried to add a ref beside the refFloat float parameter but it doesn't seem to allowed me to do that anyway but I guess I could make do with what I have in the second code sample in my forum above. I just thought I could the process simple, oh well. Thank you for responding anyway.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Object reference not set to an instance of an object 1 Answer
Anyway to pass by reference in a IEnumerator or something? 1 Answer
reset bool on timer passed by ref 1 Answer