【问题标题】:C# Reflection - FieldInfo.GetValue get variables and values from another classC# Reflection - FieldInfo.GetValue 从另一个类中获取变量和值
【发布时间】:2019-10-27 15:30:06
【问题描述】:

所以我正在尝试在调试输出中添加一些内容,并且我目前正在尝试动态获取类变量及其值。当我像这样在同一个类中添加代码时,我尝试了一些东西并让它运行得非常快:

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

有人可以告诉我我是做什么的吗?

【问题讨论】:

    标签: c# reflection getvalue


    【解决方案1】:

    您需要将目标对象实例传递给您的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);
    }
    

    【讨论】:

    • 那么你传递给它的是什么对象?在您问题顶部的代码中,您说它完全按照您的意愿工作 - 那是什么类?您需要将该实例 (this) 传递给 Error
    • 好吧,我不确定我是否以正确的方式通过课程,但这就是我正在做的事情:Debugger.Error(Context.Player.GetUsername(), e, typeof(TestingStuff)); 我想从TestingStuff 获取所有变量和值.
    • 您有一个包含变量的TestingStuff 实例,对吧?所以你应该这样做:Debugger.Error(Context.Player.GetUsername(), e, testingStuffInstance); 如果你从TestingStuff 实例内部调用Error,那么它将是:Debugger.Error(Context.Player.GetUsername(), e, this);
    • 我传递了错误的对象,所以它不起作用,谢谢。
    【解决方案2】:

    您可以将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

    【讨论】:

    • 当我使用null 我得到这个:Non-static field requires a target.
    • 你测试过if ( variable.IsStatic ) 吗?
    • 也谢谢你,从长远来看,这肯定会对我有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 2013-03-28
    • 1970-01-01
    相关资源
    最近更新 更多