我发现很难保持一致的一点是使用int
vs Int32
和bool
vs Boolean
等等。
我发现根据案例和颜色语法突出显示所有类型更为简单......
List<int>
VS
List<Int32>
后者更清洁,并保持一致性。很多代码都充斥着两者,我正在寻找一种重构工具来改变它们。
是否有任何工具可以让我将所有C#内置类型更改为其.NET Framework类型?
答案 0 :(得分:4)
如果查看StyleCop,规则SA1121实际上会强制执行与您想要的相反的操作(要求您将Int32
更改为int
)。反编译该规则并创建自己的StyleCop规则以强制执行相反的操作是相当简单的。
这不是自动的,但是在进行初始转换后,您可以将其合并到构建中,然后将任何新用途标记为错误。
答案 1 :(得分:2)
使用Roslyn CTP,以下似乎可以在实践中使用:
static SyntaxTree UpdatePredefinedTypes(this SyntaxTree tree)
{
PredefinedTypeSyntax node;
var root = tree.Root;
while (null != (node = root.DescendentNodes()
.OfType<PredefinedTypeSyntax>()
.FirstOrDefault(
syn => redefineMap.ContainsKey(syn.PlainName))))
{
var ident = Syntax.IdentifierName(redefineMap[node.PlainName]);
root = root.ReplaceNode<SyntaxNode, SyntaxNode>(
node,
ident.WithLeadingTrivia(node.GetLeadingTrivia())
.WithTrailingTrivia(node.GetTrailingTrivia()));
}
return SyntaxTree.Create(
tree.FileName,
(CompilationUnitSyntax)root,
tree.Options);
}
使用正确的redefineMap
(例如{"int","Int32"}
,{"double","Double"}
)时,以下程序已成功转换:
using System;
namespace HelloWorld {
class Program {
static void Main(string[] args) {
int x = Int32.Parse("11");
double y = x;
Console.WriteLine("Hello, World! {0}", y);
}
}
}
输出:
using System;
namespace HelloWorld {
class Program {
static void Main(String[] args) {
Int32 x = Int32.Parse("11");
Double y = x;
Console.WriteLine("Hello, World! {0}", y);
}
}
}
编译时:
var mscorlib = new AssemblyFileReference(
typeof(object).Assembly.Location);
var newTree = UpdatePredefinedTypes(tree);
var compilation = Compilation.Create("HelloWorld")
.AddReferences(mscorlib)
.AddSyntaxTrees(new[] { newTree });
var results = compilation.Emit(File.Create("helloworld.exe"));
Console.WriteLine("Success: {0}", results.Success);
foreach (var message in results.Diagnostics)
{
Console.WriteLine("{0}", message);
}
// C:\tmp\cs>roslyn-test.exe
// Success: True
//
// C:\tmp\cs>dir /b *.exe
// roslyn-test.exe
// helloworld.exe
//
// C:\tmp\cs>helloworld.exe
// Hello, World! 11
//
您甚至可以使用Workspace
功能更新整个解决方案:
var workspace = Workspace.LoadSolution(info.FullName);
var solution = workspace.CurrentSolution;
foreach (var project in solution.Projects
.Where(prj => prj.LanguageServices.Language == "C#"))
{
foreach (var doc in project.Documents
.Where(d => d.SourceCodeKind == SourceCodeKind.Regular
&& d.LanguageServices.Language == "C#"))
{
var tree = SyntaxTree.ParseCompilationUnit(
doc.GetText(),
doc.DisplayName);
var newTree = UpdatePredefinedTypes(tree);
solution = solution.UpdateDocument(doc.Id, newTree.Text);
}
}
workspace.ApplyChanges(workspace.CurrentSolution, solution);
// when running this in VS on itself it correctly updates the project!
答案 2 :(得分:1)
除了VS的搜索和替换功能外,我不知道任何工具。
当我调用静态成员
时,我通常使用c#别名进行类型声明和.NET类型int i = Int32.Parse(s);
这只是个人偏好。
答案 3 :(得分:0)
我最终写了一个宏来做这个
Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics
Public Module ReplaceCSharpBuiltInTypesWithTheirFrameworkTypes
Sub ReplaceCSharpBuiltInTypesWithTheirFrameworkTypes()
Dim dictionary As New Collections.Generic.Dictionary(Of String, String)
dictionary.Add("bool", "Boolean")
dictionary.Add("byte", "Byte")
dictionary.Add("sbyte", "SByte")
dictionary.Add("char", "Char")
dictionary.Add("decimal", "Decimal")
dictionary.Add("double", "Double")
dictionary.Add("float", "Single")
dictionary.Add("int", "Int32")
dictionary.Add("uint", "UInt32")
dictionary.Add("long", "Int64")
dictionary.Add("ulong", "UInt64")
dictionary.Add("object", "Object")
dictionary.Add("short", "Int16")
dictionary.Add("ushort", "UInt16")
dictionary.Add("string", "String")
For Each key In dictionary.Keys
DTE.Find.FindWhat = key
DTE.Find.ReplaceWith = dictionary(key)
DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument
DTE.Find.MatchCase = True
DTE.Find.MatchWholeWord = True
DTE.Find.MatchInHiddenText = False
DTE.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxLiteral
DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResultsNone
DTE.Find.Action = vsFindAction.vsFindActionReplaceAll
DTE.Find.Execute()
Next
End Sub
End Module