C # Reflection - FieldInfo.GetValue получить переменные и значения из другого класса - PullRequest
1 голос
/ 27 октября 2019

, поэтому я пытаюсь добавить кое-что к своему выводу отладки, и в настоящее время я пытаюсь динамически получить переменные класса и значения этого. Я попробовал кое-что и заработал достаточно быстро, когда добавил код такого же класса, как этот:

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("");

Это выдает следующий результат:

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

Это именно то, чтоЯ хочу, но когда я пытаюсь передать эти вещи в мой фактический вывод "Отладчик", я не могу использовать this, потому что это статический метод. Я понятия не имею, что мне следует заменить this на.

Это мой метод "отладчика":

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;
    }
    ...
}

Может кто-нибудь сказать, пожалуйста, что я делаю?

Ответы [ 2 ]

0 голосов
/ 27 октября 2019

Вам нужно будет передать экземпляр целевого объекта в метод Error, а затем использовать этот экземпляр вместо this. Обратите внимание, что вы можете получить тип класса из экземпляра объекта, поэтому вам не нужно передавать его. Вот как будет выглядеть модифицированный метод.

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;
    }
    ...
}

Затем вызовите метод следующим образом:

try
{
    ...
}
catch (Exception ex)
{
    Debugger.Error(Context.Player.GetUsername(), ex, this);
}
0 голосов
/ 27 октября 2019

Вы можете использовать null для static членов вместо ссылки на экземпляр объекта.

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

Изменить сигнатуру метода следующим образом:

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

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

...