我是Roslyn的新手。我正在編寫一個代碼修復提供程序,它將foreach
塊轉換爲遍歷Select
的結果,例如,如何使用Roslyn將語句插入具有規格化空白的塊中?
foreach (var item in new int[0].Select(i => i.ToString()))
{
...
}
到
foreach (int i in new int[0])
{
var item = i.ToString();
...
}
要做到這一點,我需要在BlockSyntax
的表示foreach
塊ForEachStatementSyntax
內開始插入語句。這裏是我的代碼爲:
var blockStatement = forEach.Statement as BlockSyntax;
if (blockStatement == null)
{
return document;
}
forEach = forEach.WithStatement(
blockStatment.WithStatements(
blockStatement.Statements.Insert(0, selectorStatement));
不幸的是,這樣做導致的空白被關閉:
foreach (int i in new int[0])
{
var item = i.ToString();
...
}
我Google了這個解決方案。我遇到了this answer,推薦使用Formatter.Format
或SyntaxNode.NormalizeWhitespace
。
我不能使用
Formatter.Format
,因爲這需要一個Workspace
參數,它看起來我沒有訪問Workspace
每Roslyn: Current Workspace in Diagnostic with code fix project。我試着在文檔的語法根目錄上使用
NormalizeWhitespace()
,但它侵入性地格式化了與修正無關的其他代碼。我試圖用它在與foreach
塊關聯的ForEachStatementSyntax
上,然後調用syntaxRoot = syntaxRoot.ReplaceNode(oldForEach, newForEach)
,但導致整個foreach
塊而不是正確縮進。namespace ConsoleApp1 { class Program { static void Main(string[] args) { var array = new int[0]; int length = array.Length; foreach (int i in array) { string item = i.ToString(); } } } }
那麼,是否可以簡單地插入在首位的正確縮進的聲明,而無需格式化其他的代碼?
感謝。
感謝這麼多運行的節點!像魅力一樣工作。出於好奇,你知道*爲什麼*添加註釋會導致語句格式化?當我看[Roslyn源代碼](http://source.roslyn.io/#Microsoft.CodeAnalysis.Workspaces/Formatting/Formatter.cs,24)時,我發現它初始化爲一個普通的'new SyntaxAnnotation()' 。 –
SyntaxAnnotation在創建時會增加一個全局ID,因此如果'someAnnotation'實際上是對同一個實例的引用,'Formatter.Annotation == someAnnotation'將僅爲真。 –