dimanche 11 juillet 2021

Using Reflection to obtain an "object" variables field name from inside a method

I'm new to reflection, and I have been searching through Stackoverflow for a while, refrencing a multitude of similar questions, however none that i have found has answered this exact question of mine...

I'm attempting to make a sort of Auto-Logger for a game-mod that contains a boat load of changeable Variables for the mod.

It's a bit inefficient to constantly type out the full length name of a field + its value for logging changes, so i'm trying to make a "universal" logging function.

In the below example, GetName(object member), is the function to get the name of the variable's field. However, within the function nameof(member) returns, well, "member" I understand WHY this is, but i cannot seem to figure out how to get it to point to the actual variable's field name.

manually typing nameof() around a variable successfully gets its name, again, i know why this is... but something like:

FunctionName(nameof(Variables.Variable3), GetValueFunction(Variables.Variable3))

seems a little obnoxious considering the endgame of this "universal" function is to make Logging the changes much eaiser without having to worry about changing 3 refrence values all over the place for the same field.

using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;

public static class Program {

        public static class Variables {
            public static bool Variable1 = false, Variable2 = false, Variable3 = false;
        }

        public static int LogCount = 1;
        public static void Log(string Msg) { Console.WriteLine(LogCount + "  |  " + Msg); LogCount++; }

        public static void GetName(object member) => Log("GetName(ref object)   |  "+nameof(member));

        public static void Main() {

            string Object1 = nameof(Variables.Variable1);
            object Object2 = Variables.Variable2;

            GetName(Object1);
            GetName(Object2);
            GetName(Variables.Variable3);

            Log("nameof(ref Variable)  |  " + Object1);
            Log("nameof(ref object)    |  " + nameof(Object2));
            Log("nameof(Variable)      |  " + nameof(Variables.Variable3));
            Log("object.ToString()     |  " + Object2.ToString());
            
            /*
            OUTPUT:
            1  |  GetName(ref object)   |  member
            2  |  GetName(ref object)   |  member
            3  |  GetName(ref object)   |  member
            4  |  nameof(ref Variable)  |  Variable1
            5  |  nameof(ref object)    |  Object2
            6  |  nameof(Variable)      |  Variable3
            7  |  object.ToString()     |  False
            */

        }

}

A desired endgame would be something like:

public static void SetValue(string MemberRef, object NewValue) {
   typeof(Variables).GetField(MemberRef).SetValue(typeof(Variables), NewValue);
}
public static void LogChange(oject obj, object NewValue){
   string Name = obj.ReflectedValue.Name;
   string Value = obj.ReflectedValue.ToString();
   SetValue(Name, NewValue);
   string GetNewValue = obj.ReflectedValue.ToString();
   Console.WriteLine(Name + ": " + Value +" => "+ GetNewValue);
}
LogChange(Variables.Variable1, True);
/*
OUTPUT:
Variable1: False => True
*/

(Note: object.ReflectedValue does not exist, it was for the example only.)





Aucun commentaire:

Enregistrer un commentaire