多态类的功能

时间:2016-08-08 07:52:22

标签: c# clr cil mdbg imetadataimport

我正在使用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
        );

1 个答案:

答案 0 :(得分:3)

将对象转换为它的基类并不会改变对象的类型,只会改变对象的感知方式。我建议你需要通过"感知"输入值和值,并使用它而不是实际类型来找到正确的方法。

"感知" type是静态确定的类型,基于您从中获取值。

  • 如果使用ICorDebugILFrame::GetArgument()从参数中获取值,则从方法签名中提取相应的参数类型。
    • 如果第一个参数和方法签名都有HasThis标志而不是ExplicitThis标志,那么请从值中获取类型。
  • 如果您使用ICorDebugILFrame::GetLocalVariable()从本地获取值,则从方法本地签名中提取类型(需要从方法标题中提取本地签名的元数据标记。)
  • 如果从运行带ICorDebugEval的方法获得值(例如属性获取器),则应使用所调用方法的返回类型(也从方法签名中提取)。
  • 如果从字段中获取值,则从字段签名中提取类型。
  • 如果您投射了一个值,那么请使用您要投射的任何类型。