【问题标题】:How to get declared variables and other definitions如何获取声明的变量和其他定义
【发布时间】:2012-10-14 21:44:29
【问题描述】:

我在嵌入式 REPL 中使用 Roslyn 脚本 API,有时我需要知道当前会话中定义了哪些变量,以及所有其他定义(类、接口...)以及引用和导入的内容命名空间。

我在 API 中找不到任何可以给我那种信息的东西,我知道它就在某个地方。

Dose Scripting API 使用了一些不寻常的实现,比如每次都更新内存中的程序集?如果是这样,如何访问该程序集。

【问题讨论】:

    标签: c# scripting roslyn


    【解决方案1】:

    我不知道是否有 Roslyn 特定的 API,但看起来您可以使用反射获取信息。这有点麻烦。我在 Visual Studio 中使用 REPL 来估计您的情况。

    using System.Reflection;
    
    Assembly.GetExecutingAssembly().DefinedTypes
    

    显示循环的每次迭代都有一个类型,加上定义的类的一些附加类型。幸运的是,Submission 类型的编号更高,即Submission#11 位于Submission#5 之后。

    REPL 中定义的变量显示为会话类型中的字段,对应于定义它的循环的执行。查看类型中所有已定义变量的调用如下:

    chosenType.GetFields(BindingFlags.Instance | BindingFlags.Public)
    

    Roslyn REPL 允许您重新声明变量,将先前声明的变量屏蔽给新的调用者。现在将“会话”视为所有提交的堆栈(最旧的在底部)。如果您向下遍历堆栈,给定字段名称的第一次出现将是 REPL 中具有该名称的活动变量。检索到的字段信息除了名称之外还提供了类型。

    这是一个示例会话(包括输出),展示了如何查看会话中声明的所有变量。

    > using System.Reflection;
    > var a = 1; 
    > var b = "c";
    > var c = from type in Assembly.GetExecutingAssembly().DefinedTypes.Reverse()
          from variable in type.GetFields(BindingFlags.Instance | BindingFlags.Public)
          select variable;
    > foreach (var info in c ) { 
         if (info.FieldType != typeof(Roslyn.Services.InteractiveHostObject)) {
             Console.WriteLine(info);
         }
      }
    System.Collections.Generic.IEnumerable`1[System.Reflection.FieldInfo] c
    System.String b
    Int32 a
    

    如果相同的名称出现两次,则列出的第一个名称就是会话中可用的名称。以上利用了返回的类型恰好按从旧到新排序的事实。您可能希望自己对其进行排序以确定。

    无论出于何种原因(可能是错误?)我必须在 foreach 循环中使用 if 语句,使用 LINQ where 子句不会给出预期的结果。

    还有更多可能有用的反射方法,具体取决于您要查找的所有内容,例如GetMethodsGetEvents。如果你想要所有东西,那么有一个GetMembersType Methods

    我希望有人可以提供一种更简单的方法。

    【讨论】:

    • 是的,我以前见过那些“提交”(作为会话的私人成员),但不知道它们如何有用,每次执行都会创建新的提交。女巫是你从 Assembly.GetExecutingAssembly().DefinedTypes 得到的。它没有让我得到真正的类型或变量。我认为它更多的是关于编译而不是会话环境。希望你看看,如果我错了,请告诉我。谢谢。
    • 现在如果我能获得当前提交的实例就好了。
    猜你喜欢
    • 2011-04-30
    • 2020-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多