我正在使用MDBG示例制作托管的.NET调试器.
MDBG示例仅在给定实例的*类上运行,而不在类内部深入层次结构中进行搜索.我能够遍历层次结构并获得所有可用方法.但是在这种情况下会出现问题:
public abstract class Base{
public Base() {SomeProp = "Base"}
public string SomeProp {get;set;}
}
public class A : Base{
public Base() {SomeProp = "A"}
public new string SomeProp {get;set;}
}
public static void Main(){
var a = new A();
var castedToBase = (Base)a;
//castedToBase.SomeProp -- expect result to be "Base" when debugging
}
问题是当我将castedToBase用作ICorDebugValue并查询它的ICorDebugValue2 :: GetExactType时,我得到一个类而不是基类.
此时,我无法再区分要调用哪个方法get_SomeProp.我希望ICorDebugValue2 :: GetExactType考虑执行的强制转换,而不总是返回基础类型.
如何理解应该调用哪种方法?
下面列出了我现在正在做的一些代码. mdbgValue表示castedToBase对象. szTypedef返回“ A”,而不是预期的“ Base”
IMetadataImport importer;
var classToken = mdbgValue.CorValue.ExactType.Class.Token;
int size;
int ptkExtends;
TypeAttributes pdwTypeDefFlags;
importer.GetTypeDefProps(classToken,
null,
0,
out size,
out pdwTypeDefFlags,
out ptkExtends
);
StringBuilder szTypedef = new StringBuilder(size);
importer.GetTypeDefProps(classToken,
szTypedef,
szTypedef.Capacity,
out size,
out pdwTypeDefFlags,
out ptkExtends
);
解决方法:
将对象强制转换为基类并不会改变对象的类型,只会改变其感知方式.我建议您需要将“感知”类型与值一起传递,并使用它来代替实际类型,以查找正确的方法.
“感知”类型是基于从何处获取值的静态确定的类型.
>如果使用ICorDebugILFrame :: GetArgument()从参数中获取值,则从方法签名中提取相应的参数类型.
>如果其第一个参数和方法签名具有HasThis标志,但没有ExplicitThis标志,则改为从值中获取类型.
>如果使用ICorDebugILFrame :: GetLocalVariable()从本地获取值,则从本地签名方法中提取类型(本地签名的元数据令牌需要从方法头中提取).
>如果通过使用ICorDebugEval运行方法(例如,属性获取器)获得了值,则应使用调用的方法的返回类型(也从方法签名中提取).
>如果您从字段中获取值,则从字段签名中提取类型.
>如果要强制转换值,则可以使用任何强制类型.