简体   繁体   中英

C# Reflection - FieldInfo.GetValue get variables and values from another class

so I'm trying to add some stuff to my debug output and I'm currently trying to dynamically get the class variables and the values of it. I tried some stuff and got it working quite fast when I added the cod ein the same class like this:

var bindingFlags = BindingFlags.Instance |
        BindingFlags.Static |
        BindingFlags.NonPublic |
        BindingFlags.Public;

Console.WriteLine("");
foreach (var variable in typeof(TestingStuff).GetFields(bindingFlags))
{
    Debugger.Debug(Context.Player.GetUsername(), $"{variable.Name}: variable.GetValue(this)}");
}
Console.WriteLine("");

This outputs the following result:

15:47:09 [Test1] _currentTarget:
15:47:09 [Test1] _currentlyPathing: False
15:47:09 [Test1] _moveToTest:
15:47:09 [Test1] _botName: Test_ZerGo01

This is exactly what I want, but when I try to pass that stuff to my actual "Debugger" output I can't use this because it's a static method. I have no idea what I should replace the this with.

This is my "debugger" method:

public static void Error(string playerName, Exception ex, Type classType = null)
{
    ...
    if (classType != null)
    {
        var bindingFlags = BindingFlags.Instance |
            BindingFlags.Static |
            BindingFlags.NonPublic |
            BindingFlags.Public;

        if (classType.GetFields(bindingFlags).Length > 1)
        {
            message += DebuggerLine("Plugin Class Variables") + nL;

            foreach (var variable in classType.GetFields(bindingFlags))
            {
                message += DebuggerLine(variable.Name, variable.GetValue(???).ToString()) + nL;
            }
        }

        message += DebuggerLine() + nL;
    }
    ...
}

Could someone please tell me what I do?

You can use null for static members instead of object instance reference.

if ( variable.IsStatic ) 
  message += DebuggerLine(variable.Name, variable.GetValue(null).ToString()) + nL;
else
if ( instance != null )
  message += DebuggerLine(variable.Name, variable.GetValue(instance).ToString()) + nL;
else
  // Manage method call mistmatch: 
  // add an error string to the message or do nothing or what you want

Modify the method signature as:

public static void Error(string playerName,
                         Exception ex,
                         Type classType = null,
                         object instance = null)

https://docs.microsoft.com/dotnet/api/system.reflection.fieldinfo.getvalue

You will need to pass the target object instance to your Error method and then use that instance in place of this . Note that you can get the class type from the object instance, so you don't have to pass that in. Here is what the modified method would look like.

public static void Error(string playerName, Exception ex, object instance = null)
{
    ...
    if (instance != null)
    {
        var bindingFlags = BindingFlags.Instance |
            BindingFlags.Static |
            BindingFlags.NonPublic |
            BindingFlags.Public;

        Type classType = instance.GetType();
        if (classType.GetFields(bindingFlags).Length > 1)
        {
            message += DebuggerLine("Plugin Class Variables") + nL;

            foreach (var variable in classType.GetFields(bindingFlags))
            {
                message += DebuggerLine(variable.Name, variable.GetValue(instance).ToString()) + nL;
            }
        }

        message += DebuggerLine() + nL;
    }
    ...
}

Then, call the method like this:

try
{
    ...
}
catch (Exception ex)
{
    Debugger.Error(Context.Player.GetUsername(), ex, this);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM