2012-10-24 46 views
4

我在嵌入式REPL中使用Roslyn腳本API,不時需要知道當前會話中定義了哪些變量,以及所有其他定義(類,接口)。 ..)以及引用和導入的命名空間。如何獲取聲明的變量和其他定義

我在API中找不到任何東西可以給我那種信息,我知道它在某處。

劑量腳本API使用一些不尋常的實現,就像每次更新內存中的程序集?如果是的話如何訪問該程序集。

回答

6

我不知道是否有一個Roslyn特定的API,但它看起來像你可以使用反射得到的信息。這有點麻煩。我在Visual Studio中使用REPL來近似您的情況。

using System.Reflection; 

Assembly.GetExecutingAssembly().DefinedTypes 

顯示循環的每次迭代都有一個類型,併爲定義的類增加了一些額外的類型。幸運的是,Submission類型被編號,後者提交的號碼較高,即Submission#11Submission#5之後。

在REPL中定義的變量在會話類型中顯示爲字段,與執行定義的循環相對應。呼叫看到一個類型的所有定義的變量將如下所示:

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

的羅斯林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可能?)我必須使用if語句在foreach循環中,使用LINQ where子句不會給出預期的結果。

還有很多反射方法可能會有用,具體取決於您想要查找的內容,如GetMethodsGetEvents。如果你想要一切,那麼有一個GetMembersType Methods

我希望有人能提供一個更簡單的方法。

+0

是的,我已經看過那些'提交'之前(作爲會議的私人成員),但不知道他們如何有用,每個執行創建新的提交。女巫是你從Assembly.GetExecutingAssembly()。DefinedTypes得到的。它dosnt讓我真正的類型或變量。我認爲它比編譯會話環境更多。希望你看看並告訴我,如果我錯了,謝謝。 – KA1

+1

@ KA100我已編輯我的答案,包括一個例子。 – vossad01

+0

現在,如果我只能獲得當前提交的實例。 – jnm2