C# Get the property name a Func<T> is set to

97 Views Asked by At

I have a Func<T> delegate points to a property/field from another class. I'd like to get the name of the target property/field from the Func<T> but I'm only seeing '<InitialiseModel>b__7_0' as the Method Name.

public class PointerVariable<T>
{
    private Func<T> _getter;
    public void AddGetter(Func<T> getter)
    {
        _getter = getter;
    }

}


public class MonoBehaviour
{
    protected bool enabled;
}

public class Model : MonoBehaviour
{
    protected PointerVariable<bool> _isEnabledVar;
        
    public virtual void InitialiseModel() 
    {
       _isEnabledVar.AddGetter(() => enabled);
    }
}

I would like to get the field name 'enabled' from the Func but can't seem to find a way.

1

There are 1 best solutions below

1
Tore Aurstad On

I have looked upon your example code and could not extract any passed in name of which member you passed in using a Func. Switching to Expression of Func allows me to access the passed in field name. This is very fine tuned to only expect the type of expression you are using here, getting the Right-Hand-Side of a lambda expression in C# requires more code to handly different cases.

Changes in your code was an added null check and switching to use Expression of Func in the argument of AddGetter method. The code was ran inside Linqpad and I added a main method to run initialization code to test it out. I also added a public proxy property to read out the IsEnabledVar.

Sample code in Linqpad 7

void Main()
{
    var model = new Model();
    model.InitialiseModel();
    Console.WriteLine($"Passed in field name : {model.IsEnabledVar.GetterFieldName}");
}

public class PointerVariable<T>
{
    private Func<T> _getter;
    private string _getterFieldName;
    
    public string GetterFieldName => _getterFieldName;
    
    public void AddGetter(Expression<Func<T>> getter)   
    {
        _getterFieldName = (getter?.Body as MemberExpression)?.Member?.Name;
        _getter = getter.Compile();     
    }
}


public class MonoBehaviour
{
    protected bool enabled;
}

public class Model : MonoBehaviour
{
    protected PointerVariable<bool> _isEnabledVar;
    
    public PointerVariable<bool> IsEnabledVar => _isEnabledVar;

    public virtual void InitialiseModel()
    {
        if (_isEnabledVar == null){
            _isEnabledVar = new UserQuery.PointerVariable<bool>();
        }
        _isEnabledVar.AddGetter(() => enabled);
    }
}