C# 多态类的Func求值

C# 多态类的Func求值,c#,clr,cil,mdbg,imetadataimport,C#,Clr,Cil,Mdbg,Imetadataimport,我正在使用MDBG示例制作托管.NET调试器 MDBG sample只在给定实例的顶级类上操作,而不在类层次结构的深层搜索。我能够遍历层次结构并获得所有可用的方法。但在这种情况下会出现一个问题: public abstract class Base{ public Base() {SomeProp = "Base"} public string SomeProp {get;set;} } public class A : Base{

我正在使用MDBG示例制作托管.NET调试器

MDBG sample只在给定实例的顶级类上操作,而不在类层次结构的深层搜索。我能够遍历层次结构并获得所有可用的方法。但在这种情况下会出现一个问题:

    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表示铸造数据库对象。szTypedef返回“A”而不是预期的“Base”


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

“感知”类型是基于从何处获取值的静态确定类型

  • 如果使用
    ICorDebugILFrame::GetArgument()
    从参数中获取值,则从方法签名中提取相应的参数类型。
    • 如果它是第一个参数,并且方法签名具有
      HasThis
      标志,但没有
      ExplicitThis
      标志,则改为从该值获取类型
  • 如果使用
    ICorDebugILFrame::GetLocalVariable()
    从本地获取值,则从方法本地签名中提取类型(需要从方法头中提取本地签名的元数据标记)
  • 如果您是通过使用
    ICorDebugEval
    运行方法(例如属性getter)获得值的,那么您应该使用调用的方法的返回类型(也从方法签名中提取)
  • 如果从字段中获取值,则从字段签名中提取类型
  • 如果您强制转换一个值,则使用您要强制转换的任何类型

将对象强制转换为其基类不会改变对象,只会改变对象的感知方式。我建议您需要将“感知”类型与值一起传递,并使用该类型而不是实际类型来找到正确的方法。@BrianReichle感谢您的建议!但我没有“感知”类型,调试器如何知道对对象执行了什么强制转换?也许“静态确定类型”比“感知”类型更好。您可以从任何获得值(字段类型、参数类型、方法/属性返回类型等)的地方获取它@BrianReichle您是指编译器时间类型吗?因此,为了得到静态类型,我应该以某种方式调用roslyn,给它我的运行时已知的类名、方法名和变量名?不,当我说“静态确定类型”时,我指的是通过查看代码/元数据而不是通过运行它或检查当前执行状态而得到的类型。因此,如果从参数中获取值,静态确定的类型就是参数的类型。如果你是从一处房产得到的,那就是房产的类型。谢谢你,布莱恩!你的回答救了我,使我免于淹没在怀疑的海洋中。我想现在我开始明白你的意思了,但我需要一些时间来尝试一下,看看我能做到什么。在概念层面上唯一尚不清楚的是最后一段关于演员阵容的内容。在这种情况下,我没有要解析的方法签名/字段签名,因此我将从何处获得我要转换到的类型?这是基于这样的假设,即在某个时候,您可能希望在调试器中计算表达式时支持转换。例如,
((A)铸造数据库)。一些项目。。。也许现在就担心这个还为时过早:)是的,你是对的,当我输入你提到的一些表达时,考虑起来就辩护地为时过早!我想的是一些强制转换代码,而不是在调试器表达式中。这就像问题的例子:
var castedToBase=(Base)acastedToBase.SomeProp
。目前我坚持对油田和房地产进行评估,没有比这更先进的了。。。
    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
        );