c# - 使用 ICorDebugEval 的通用类型 func-eval

标签 c# generics clr cil imetadataimport

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

MDBG 不支持属性 getter 评估,我正在尝试添加这一点。请考虑以下类结构:

    public abstract class Base<T>{
        public string SomeProp {get;set;}
    }

    public class A : Base<int>{

    }

在某个时间点,我正在创建 A 的实例并在断点处停止以评估它的状态。

在我的调试器的监 window 口中,我引入了“this.SomeProp”,它应该对此对象执行 get_SomeProp 方法的函数评估,并针对给定的情况返回空值。

我遇到的第一个问题是 get_SomeProp 是在基类上定义的,所以我必须遍历类层次结构中的所有 TypeDefs/TypeRefs/TypeSpecs 才能找到函数。

但是找到之后,调用

   ICorDebugEval.CallFunction(function.CorFunction, new[] {@object.CorValue});

导致:TypeLoadException:泛型类型在程序集中使用了错误数量的泛型参数

正如我所意识到的,这是因为非泛型函数是在泛型类 (Base) 中定义的,所以当我评估它时,我还应该指出类的泛型参数。

这可以用

来完成
  ICorDebugEval2.CallParameterizedFunction(function.CorFunction,
    genericArguments,
    functionArguments);

问题是我不知道如何提取类通用参数的类型,只有我想评估的函数和我想评估它的实例。

这是我目前正在使用的一些代码:

    private MDbgValue EvaluatePropertyGetter(MDbgFrame scope, MDbgValue @object, string propertyName) {
        var propertyGetter = $"get_{propertyName}";
        var function = ResolveFunctionName(
            scope.Function.Module.CorModule.Name,
            @object.TypeName,
            propertyGetter,
            scope.Thread.CorThread.AppDomain);

        if (function == null) {
            throw new MDbgValueException("Function '" + propertyGetter + "' not found.");
        }

        var eval = Threads.Active.CorThread.CreateEval();
        var typeToken = function.CorFunction.Class.Token;
        var type = function.Module.Importer.GetType(typeToken); //checked that type containing function is generic
        if (type.IsGenericType) {
            //------------->need to get class'es generic param types<------------
            var genericType1 = this.ResolveType("System.Object"); // just a stub
            eval.CallParameterizedFunction(function.CorFunction, new CorType[] {genericType1}, new[] {@object.CorValue});
        }
        else {
            eval.CallFunction(function.CorFunction, new[] {@object.CorValue});
        }

        Go().WaitOne();
        if (!(StopReason is EvalCompleteStopReason)) {
            // we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason
            Console.WriteLine("Func-eval not fully completed and debuggee has stopped");
            Console.WriteLine("Result of funceval won't be printed when finished.");
        }
        else {
            eval = (StopReason as EvalCompleteStopReason).Eval;
            Debug.Assert(eval != null);

            var cv = eval.Result;
            if (cv != null) {
                var mv = new MDbgValue(this, cv);
                return mv;
            }
        }
        return null;
    }

非常感谢任何建议/建议!

问候,


解决方案

感谢@Brian Reichle 出色的回答,我想出了这个解决方案:

 if (type.IsGenericType) {
            //getting Type's Generic parameters
            var typeParams = GetGenericArgs(@object.CorValue.ExactType, function.CorFunction.Class.Token);
            eval.CallParameterizedFunction(function.CorFunction, typeParams.ToArray(), new[] {@object.CorValue});
        }

以及函数本身:

 private List<CorType> GetGenericArgs(CorType corType, int classTk) {
        if (corType == null)
            return null;
        List<CorType> list = new List<CorType>();

        var param =corType.TypeParameters;
        var args = GetGenericArgs(corType.Base, classTk);

        if (classTk == corType.Class.Token) {
            list.AddRange(param.Cast<CorType>());
        }

        if (args != null) {
            list.AddRange(args);}

        return list;
    }

最佳答案

您可以使用 ICorDebugValue2::GetExactType在表示 A 实例的值对象上获取类型 A 的 ICorDebugType , ICorDebugType::GetBase()得到它的基类(Base<int>)和ICorDebugType::EnumerateTypeParameters在基类型上获取它的类型参数。

关于c# - 使用 ICorDebugEval 的通用类型 func-eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38723274/

相关文章:

c# - .NET/C# 到在 Linux 上运行的 MySql - 第一个命令出现异常,但后续命令确实有效

c# - 网络利用率 - AccountManagement 与 DirectoryServices

.net - GC.Collect 与否?

c# - 如何使用 TcpListener/Client 通过 tcp 发送文件? SocketException问题

c# - 如何在 C# 中获取当前登录的 Visual Studio 用户的名称?

c# - 返回通用接口(interface)时出错

java - 从类型删除的 Java 对象获取原始类

java - 使用泛型的不兼容类型

python - 导入 clr 导入错误 : No module named clr

.net - 当 .NET 崩溃报告中的 P9 "bucket"包含乱码而不是导致崩溃的异常名称时,这意味着什么?