Skip to content

Instantly share code, notes, and snippets.

@wilbefast
Last active August 29, 2015 14:02
Show Gist options
  • Save wilbefast/4e96dfc060999c4a385c to your computer and use it in GitHub Desktop.
Save wilbefast/4e96dfc060999c4a385c to your computer and use it in GitHub Desktop.
Fun with lambdas and scoping in C#
public abstract class AbstractSkeletonTrackingDevice : AbstractControlDevice
{
// ...
protected void registerExerciseInput(SkeletonExercise new_exercise)
{
// ...
foreach(string axis_name in new_exercise.axisNames)
{
// The following doesn't work :
registerAxis(axis_name, () => (new_exercise.skeleton == null) ? 0.0f : new_exercise.getAxis(axis_name));
// This is because the lambda uses a reference to 'axis_name' rather than a copy of its value.
// As a result in all the lambdas' scopes the value of 'axis_name' is the final value it took at the end of
// the iteration. In this case the axis names are "X" and "Y" so 'axis_name' is always equal to "Y" in the
// lambdas' scope.
// The following doesn't work either :
registerAxis(axis_name, () =>
{
string axis_name_copy = String.Copy(axis_name);
registerAxis(axis_name_copy, () => (new_exercise.skeleton == null) ? 0.0f : new_exercise.getAxis(axis_name_copy));
}
// This is because as a copy is being made of the reference to 'axis_name', the iterator variable. The copy needs
// to be made *before* being captured by the closure!
// Thus the only working solution is the following
string axis_name_copy = String.Copy(axis_name);
registerAxis(axis_name, () => (new_exercise.skeleton == null) ? 0.0f : new_exercise.getAxis(axis_name_copy));
// note that 'axis_name_copy' only needs to be used within the lambdas' scope : 'axis_name' can be used
// for the key registration.
}
// ...
}
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment