我认为Roslyn无法重命名用作列表元素的类的字段。 视觉工作室重构有什么解决方案吗?
如下面的代码所示,如果将元素显式转换为局部变量,则将成功重命名。但这不是最终的解决方案。
// ** Reference code of Simple Class's Field1 => renaming failed!
Console.WriteLine(SimpleList[0].Field1);
以下代码在ConsoleApplication项目上进行了测试。
private void Roslyn_rename_failed()
{
const string codes = @"
using System;
public class Simple
{
public int Field1; // <== Field to rename
}
public class Usage
{
public List<Simple> SimpleList;
public Usage()
{
// make list of Simple instance
SimpleList = new List<Simple>();
SimpleList.Add(new Simple());
this.Do();
}
public void Do()
{
Simple simple = SimpleList[0];
// ** Reference 1 of Simple's Field1 => renaming succeeded!
// Console.WriteLine(simple.Field1Renamed); // <== Renamed result
Console.WriteLine(simple.Field1);
var simple2 = SimpleList[0];
// ** Reference 2 of Simple's Field1 => renaming failed!
Console.WriteLine(simple2.Field1);
// ** Reference 3 of Simple's Field1 => renaming failed!
Console.WriteLine(SimpleList[0].Field1);
}
}";
// 1. solution setup
var workspace = new AdhocWorkspace();
var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(),
"roslyn-rename-failed", "roslyn-rename-failed", LanguageNames.CSharp);
var project = workspace.AddProject(projectInfo);
var sourceText = SourceText.From(codes);
var document = project.AddDocument("RenameFailed.cs", sourceText);
var newProject = document.Project;
var newSolution = document.Project.Solution;
// 2. refactoring rename on Simple::Field1
var newSolutions = from doc in newProject.Documents
let root = doc.GetSyntaxRootAsync().Result
let sm = doc.GetSemanticModelAsync().Result
from cds in root.DescendantNodesAndSelf().OfType<ClassDeclarationSyntax>()
let cdsSymbol = (ITypeSymbol) sm.GetDeclaredSymbol(cds)
from field in cdsSymbol.GetMembers().OfType<IFieldSymbol>().Where(m => m.Name == "Field1")
let newName = field.Name + "Renamed"
select Renamer.RenameSymbolAsync(newSolution, field, newName, workspace.Options).Result;
newSolution = newSolutions.FirstOrDefault();
// 3. print renamed codes
var newCodes = newSolution?.GetDocument(document.Id).GetSyntaxRootAsync().Result.ToFullString();
Console.WriteLine(newCodes);
}