C# 反射 - FieldInfo.GetValue 从另一个 class 获取变量和值
C# Reflection - FieldInfo.GetValue get variables and values from another class
所以我正在尝试向我的调试输出添加一些东西,我目前正在尝试动态获取 class 变量及其值。我尝试了一些东西,当我在相同的 class 中添加代码时,它运行得非常快,如下所示:
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
这正是我想要的,但是当我尝试将这些东西传递到我的实际 "Debugger" 输出时,我无法使用 this
,因为它是一个静态方法。我不知道应该用什么替换 this
。
这是我的"debugger"方法:
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;
}
...
}
有人可以告诉我我是做什么的吗?
您可以对 static
成员使用 null
而不是对象实例引用。
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
您需要将目标对象实例传递给您的 Error
方法,然后使用该实例代替 this
。请注意,您可以从对象实例中获取 class 类型,因此您不必将其传入。修改后的方法如下所示。
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);
}
所以我正在尝试向我的调试输出添加一些东西,我目前正在尝试动态获取 class 变量及其值。我尝试了一些东西,当我在相同的 class 中添加代码时,它运行得非常快,如下所示:
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
这正是我想要的,但是当我尝试将这些东西传递到我的实际 "Debugger" 输出时,我无法使用 this
,因为它是一个静态方法。我不知道应该用什么替换 this
。
这是我的"debugger"方法:
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;
}
...
}
有人可以告诉我我是做什么的吗?
您可以对 static
成员使用 null
而不是对象实例引用。
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
您需要将目标对象实例传递给您的 Error
方法,然后使用该实例代替 this
。请注意,您可以从对象实例中获取 class 类型,因此您不必将其传入。修改后的方法如下所示。
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);
}