多态 类 上的函数求值
Func-eval on polymorphic classes
我正在使用 MDBG 示例制作托管 .NET 调试器。
MDBG 示例仅在给定实例的顶层 class 上运行,而不是在 class 层次结构的深处进行搜索。我能够遍历层次结构并获得所有可用的方法。但是在这种情况下会出现问题:
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 class 而不是 Base class。
那时我无法再区分要调用哪个方法 get_SomeProp 。我希望 ICorDebugValue2::GetExactType 考虑执行的转换而不是 return 总是底层类型。
我如何理解应该调用哪个方法?
下面列出了我现在正在做的一些代码。 mdbgValue 表示 castedToBase 对象。 szTypedef returns "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
);
将 object 转换为它的基础 class 不会改变 object 的类型,只会改变它的感知方式。我建议您需要将 "perceived" 类型与值一起传递,并使用它而不是实际类型来找到正确的方法。
"perceived" 类型是根据您获取值的位置静态确定的类型。
- 如果您使用
ICorDebugILFrame::GetArgument()
从参数中获取值,则从方法签名中提取相应的参数类型。
- 如果它的第一个参数和方法签名具有
HasThis
标志但没有 ExplicitThis
标志,则从值中获取类型。
- 如果您使用
ICorDebugILFrame::GetLocalVariable()
从本地获取值,则从方法本地签名中提取类型(本地签名的元数据标记需要从方法 header 中提取。)
- 如果您从 运行 方法中获得了
ICorDebugEval
的值(例如 属性 getter),那么您应该使用 return您调用的方法的类型(也从方法签名中提取。)
- 如果您从字段中获取值,则从字段签名中提取类型。
- 如果您投射一个值,则使用您投射到的任何类型。
我正在使用 MDBG 示例制作托管 .NET 调试器。
MDBG 示例仅在给定实例的顶层 class 上运行,而不是在 class 层次结构的深处进行搜索。我能够遍历层次结构并获得所有可用的方法。但是在这种情况下会出现问题:
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 class 而不是 Base class。 那时我无法再区分要调用哪个方法 get_SomeProp 。我希望 ICorDebugValue2::GetExactType 考虑执行的转换而不是 return 总是底层类型。
我如何理解应该调用哪个方法?
下面列出了我现在正在做的一些代码。 mdbgValue 表示 castedToBase 对象。 szTypedef returns "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
);
将 object 转换为它的基础 class 不会改变 object 的类型,只会改变它的感知方式。我建议您需要将 "perceived" 类型与值一起传递,并使用它而不是实际类型来找到正确的方法。
"perceived" 类型是根据您获取值的位置静态确定的类型。
- 如果您使用
ICorDebugILFrame::GetArgument()
从参数中获取值,则从方法签名中提取相应的参数类型。- 如果它的第一个参数和方法签名具有
HasThis
标志但没有ExplicitThis
标志,则从值中获取类型。
- 如果它的第一个参数和方法签名具有
- 如果您使用
ICorDebugILFrame::GetLocalVariable()
从本地获取值,则从方法本地签名中提取类型(本地签名的元数据标记需要从方法 header 中提取。) - 如果您从 运行 方法中获得了
ICorDebugEval
的值(例如 属性 getter),那么您应该使用 return您调用的方法的类型(也从方法签名中提取。) - 如果您从字段中获取值,则从字段签名中提取类型。
- 如果您投射一个值,则使用您投射到的任何类型。