C# 如何获取声明的变量和其他定义

C# 如何获取声明的变量和其他定义,c#,scripting,roslyn,C#,Scripting,Roslyn,我在embedded REPL中使用Roslyn脚本API,有时我需要知道在当前会话中定义了哪些变量,以及对所有其他定义(类、接口…)的定义,以及引用和导入的命名空间 我在API中找不到任何东西可以给我这种信息,我知道它就在某处 脚本API是否使用了一些不寻常的实现,比如每次更新内存中的程序集?如果有,如何访问该程序集。我不知道是否有特定于Roslyn的API,但看起来您可以使用反射获取信息。这有点烦人。我正在使用Visual Studio中的REPL来近似您的情况 using System.R

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

我在API中找不到任何东西可以给我这种信息,我知道它就在某处


脚本API是否使用了一些不寻常的实现,比如每次更新内存中的程序集?如果有,如何访问该程序集。

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

using System.Reflection;

Assembly.GetExecutingAssembly().DefinedTypes
显示循环的每个迭代都有一个类型,另外还有一些定义的类。幸运的是,
提交
类型被编号,后面的提交有更高的编号,即
提交#11
提交#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
如果同一名称出现两次,则表明列出的第一个名称是会话中可用的名称。上述方法利用了一个事实,即返回的类型恰好是按从最早到最年轻的顺序排列的。您可能希望自己对其进行排序以确定

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

根据您想要查找的内容,还有更多的反射方法可能很有用,例如
GetMethods
GetEvents
。如果您想要所有东西,那么有一个
GetMembers
请参阅


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

是的,我以前见过这些“提交”(作为会话的私人成员),但不知道它们如何有用,每次执行都会创建新的提交。这是从Assembly.GetExecutionGassembly()定义的类型中得到的。它没有给我真正的类型或变量。我认为与其说是会话环境,不如说是编译。希望你能看看并告诉我我是否错了。谢谢。现在,如果我能获得当前提交的实例就好了。