-1

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
    You give it a `() => enabled` lambda expression, not the field/property itself -> you seem to get the internal "name" of the lambda expression ... you could fake it and create your own method `private bool IsEnabled() => enabled;` – derHugo Jul 27 '23 at 11:05
  • 6
    You obviously cannot do this with `Func` as it is delegate and you cannot analyze it source on runtime ... you may do this with `Expression>` [like this](https://stackoverflow.com/questions/671968/retrieving-property-name-from-lambda-expression) – Selvin Jul 27 '23 at 11:21
  • There is no field named `enabled` in your sample code. Can you correct it? – Matthew Watson Jul 27 '23 at 11:21
  • 1
    what if a client does `() => true` instead? Your assumption "there's a property" isn't true, so you can't get "its name". You could provide an `Expression>` which may *compile* to a `Func`, though. But that won't solve that forementioned problem, clients can still provide something that is not a property. What are you doing with that `Func`? What's the purpose of it? – MakePeaceGreatAgain Jul 27 '23 at 11:43
  • @MatthewWatson sorry 'enabled' is in the parent 'MonoBehaviour' class. Will add for reference. – Jake Slack Jul 28 '23 at 12:23
  • @MakePeaceGreatAgain the MonoBehaviour class is part of the UntiyEngine and I cannot alter its source. I'm looking to display a 'Model' in the Editor's Inspector. I have full control over how 'PointerVariable' is rendered in the Inspector and I want this to get/set the field/property it is pointing to (in this case 'enabled'). I would like to show in the Inspector the actual variable the 'PointerVar' is changing eg. "MonoBehaviour.enabled". The variable it is linked to could be any number of fields/properties that belong in UnityEngine classes. – Jake Slack Jul 28 '23 at 12:31

1 Answers1

0

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);
    }
}
Tore Aurstad
  • 3,189
  • 1
  • 27
  • 22
  • Why do you post a foto of your code and the code together? Code should *always* be posted as text, not as image. Apart from this you don't need to compile the expression to get the properties name. However depending on what OP is ding with the func, you may need to do. – MakePeaceGreatAgain Jul 31 '23 at 07:27