Updating a static field by passing it as a method argument

My app will involve a lot of modifying of static fields. I’m wondering how to update the static fields from different classes by passing them as a method argument to a utility setter method.

internal static class Hero1
{
  public static bool awesomeAbility = false;
  public static bool anotherAwesomeAbility = false;
}

internal static class Hero2
{
  public static bool awesomeAbility = false;
  public static bool anotherAwesomeAbility = false;
}

internal static class Utils
{
  public static async void ToggleAbility(ability, bool value)
  {
    Logger.Write($@"{ability} = {value}");
    ability = value;
  }
}

// example usage....
ToggleAbility(Hero1.awesomeAbility, true);
ToggleAbility(Hero2.anotherAwesomeAbility, false);

>Solution :

It is possible to do this if you allow the caller to pass an expression tree (Expression<Func<bool>>), then you can get the field referenced by the expression tree as a FieldInfo.

async void ToggleAbility(Expression<Func<bool>> field, bool value) {
    if (field.Body is MemberExpression memberExpression &&
        memberExpression.Member is FieldInfo fieldInfo) {
        
        // instead of field.Body, you can also use fieldInfo.Name for a simple name
        Logger.Write($@"{field.Body} = {fieldInfo.GetValue(null)}");

        // this sets the field's value
        fieldInfo.SetValue(null, value);

        // if you want to set it back asynchronously some time later...
        // await Task.Delay(...);
        // fieldInfo.SetValue(null, !value);
    } else {
        // the expression tree is not an access to a public static field
        // you could e.g. throw an exception 
    }
}

Usage:

ToggleAbility(() => Hero1.awesomeAbility, true);

If your method doesn’t need to be async, you can also pass the field in as a ref parameter, as lidqy’s answer shows.

Leave a Reply