当我从这段代码中提取方法时,最终结果是global::System.Int32[]
列表作为NewMethod
的参数:
using System;
public class Program
{
public static void Main(string[] args)
{
var list = new int[] {3, 2, 1 };
foreach(var i in list) Console.WriteLine(i);
}
}
最终结果:
using System;
public class Program
{
public static void Main(string[] args)
{
var list = new int[] { 3, 2, 1 };
NewMethod(list);
}
private static void NewMethod(**global::System.Int32[] list**)
{
foreach (var i in list) Console.WriteLine(i);
}
}
我使用这个这个Roslyn类来提取方法:
var options = new ExtractMethodGenerationOptions()
{CodeGenerationOptions = CodeGenerationOptions.GetDefault(document.Project.Services),
ExtractOptions = new() { DontPutOutOrRefOnStruct = true}}
var service = new CSharpExtractMethodService() as IExtractMethodService;
var extract = await service.ExtractMethodAsync(document, span, false,options, CancellationToken.None);
var result = extract.DocumentWithoutFinalFormatting;
为什么我有global::
,当我用Visual Studio提取方法时,NewMethod
有简单的int[]
列表作为方法参数?
获取最终文档,然后通过我们的Simplifier API运行它。通常,当我们进行重构时,我们在内部将名称展开为完全限定的东西(global::和all),并在最后一次传递时将所有内容清理回来。这允许我们将代码移动到其他文件或地方,这些地方可能需要不同的限定符。
在这段代码中,我将global::替换为简单类型:
public class MySimplifier
{
public static async Task<Document> SimplifyTypes(Document document)
{
var root = await document.GetSyntaxRootAsync().ConfigureAwait(false);
var editor = await DocumentEditor.CreateAsync(document).ConfigureAwait(false);
var nodesToReplace = root.DescendantNodesAndSelf()
.OfType<TypeSyntax>()
.Where(n => n.ToString().StartsWith("global::"))
.ToList();
foreach (var node in nodesToReplace)
{
var typeName = node.ToString().Substring("global::".Length);
var simpleType = GetSimpleType(typeName);
if (simpleType != null)
{
var newType = SyntaxFactory.ParseTypeName(simpleType);
editor.ReplaceNode(node, newType);
}
}
return editor.GetChangedDocument();
}
private static string GetSimpleType(string typeName)
{
switch (typeName)
{
case "System.Boolean":
return "bool";
case "System.Byte":
return "byte";
case "System.Char":
return "char";
case "System.Decimal":
return "decimal";
case "System.Double":
return "double";
case "System.Int16":
return "short";
case "System.Int32":
return "int";
case "System.Int64":
return "long";
case "System.SByte":
return "sbyte";
case "System.Single":
return "float";
case "System.String":
return "string";
case "System.UInt16":
return "ushort";
case "System.UInt32":
return "uint";
case "System.UInt64":
return "ulong";
default:
return null;
}
}
}
}