1

Okay so I made a class to take an input script and a property name. It finds the property and then displays it when Display() is called [The display method is overridden by a child class]. However, there is one problem that I have with it and that is how do I cache what FieldInfo.GetValue() returns? It would be preferable to have a pointer or something to reuse once the variable containing what I need is found since reflection is costly.

public class PropertyDisplayer : MonoBehaviour
    {
        public string PropertyName;
        public Object TargetObject;

        public object _TargetObject;
        public FieldInfo Property;

        void Start()
        {
            _TargetObject = TargetObject;

            if (!PropertyName.Contains("."))
            {
                Property = _TargetObject.GetType().GetField(PropertyName);
            }
            else
            {
                string[] split = PropertyName.Split('.');

                Property = _TargetObject.GetType().GetField(split[0]);

                for (int i = 1; i != split.Length; i++)
                {
                    _TargetObject = Property.GetValue(_TargetObject);
                    Property = Property.FieldType.GetField(split[i]);
                }
            }
        }

        public virtual void Display()
        {

        }
    }
Toxic Cookie
  • 73
  • 1
  • 7
  • Do you actually have a performance problem with this code? Have you tested it? Reflection is generally cached for you internally anyway. – DavidG Dec 17 '20 at 15:21
  • Not really sure I understand the question. Are you looking to cache the value, or cache *the way to get the value*? If the latter, see [Is there a way to create a delegate to get and set values for a FieldInfo?](https://stackoverflow.com/q/16073091/3744182). Note that it's easier to create delegates for get and set properties rather than fields, you can just use `Delegate.CreateDelegate()` for example. See e.g. [How do I create a delegate for a .NET property?](https://stackoverflow.com/q/724143/3744182). – dbc Dec 17 '20 at 15:26
  • @dbc My goal is to generically cache the variable holding the value itself so that it can be read with little performance cost. If that's not possible then I suppose a more optimized method of obtaining it would also work. – Toxic Cookie Dec 17 '20 at 15:31
  • @DavidG I haven't tested how the performance would be at a large scale but at a small scale it seems fine on the surface at least. I'd just rather not use more resources than needed. – Toxic Cookie Dec 17 '20 at 15:32
  • When talking about performance, I usually refer people to this article https://ericlippert.com/2012/12/17/performance-rant/ – DavidG Dec 17 '20 at 15:35
  • @DavidG Yeah that's fair. I'm perfectly content with the slight performance impact of some reflection but I just figured I could net some more if I adjust my code a little by somehow caching the thing I need rather than repeatedly querying for it. – Toxic Cookie Dec 17 '20 at 15:40

2 Answers2

1

Use the dynamitey library, it will cache all reflection calls transparently for you and make them near normal call speed. More info here: https://github.com/ekonbenefits/dynamitey

jjxtra
  • 20,415
  • 16
  • 100
  • 140
-1

You can store the results of the FieldInfo.GetValue() call in a new member field that is of type "object". (This IS, effectively, a pointer)

Then, in your Display() override, simply cast this member to the appropriate class, in order to access its members.

Glurth
  • 290
  • 1
  • 17