3

我正在使用 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 时,我得到的是 A 类而不是 Base 类。那时我无法再区分调用哪个方法 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
        );
4

1 回答 1

3

将对象转换为它的基类不会改变对象的类型,只会改变它的感知方式。我建议您需要将“感知”类型与值一起传递,并使用它而不是实际类型来找到正确的方法。

“感知”类型是根据您从何处获得值而静态确定的类型。

  • 如果您使用 获取参数的值,ICorDebugILFrame::GetArgument()则从方法签名中提取相应的参数类型。
    • 如果它的第一个参数和方法签名有HasThis标志但没有ExplicitThis标志,那么从值中获取类型。
  • 如果您从本地使用获取值,ICorDebugILFrame::GetLocalVariable()则从方法本地签名中提取类型(本地签名的元数据令牌需要从方法头中提取。)
  • 如果您通过使用(例如属性 getter)运行方法获得值ICorDebugEval,那么您应该使用您调用的方法的返回类型(也从方法签名中提取。)
  • 如果您从字段中获取值,则从字段签名中提取类型。
  • 如果您转换一个值,则使用您要转换的任何类型。
于 2016-08-08T11:58:53.077 回答