C# 是否有任何工具允许我将所有C内置类型更改为其.NET Framework类型?

C# 是否有任何工具允许我将所有C内置类型更改为其.NET Framework类型?,c#,C#,我发现很难保持一致的一件事是使用int vs Int32和bool vs Boolean等等 我发现通过大小写和颜色语法突出显示来识别所有类型更简单 List<int> vs 后者更干净,保持一致性。很多代码都同时包含了这两个方面,我正在寻找一个重构工具来改变它们 是否有任何工具允许我将所有C内置类型更改为其.NET Framework类型?除了VS的搜索和替换功能外,我不知道其他任何工具 在调用静态成员时,我通常将c别名用于类型声明和.NET类型 int i = Int32.Pa

我发现很难保持一致的一件事是使用int vs Int32和bool vs Boolean等等

我发现通过大小写和颜色语法突出显示来识别所有类型更简单

List<int>
vs

后者更干净,保持一致性。很多代码都同时包含了这两个方面,我正在寻找一个重构工具来改变它们


是否有任何工具允许我将所有C内置类型更改为其.NET Framework类型?

除了VS的搜索和替换功能外,我不知道其他任何工具

在调用静态成员时,我通常将c别名用于类型声明和.NET类型

int i = Int32.Parse(s);

这只是个人喜好。

除了VS的搜索和替换功能外,我不知道其他工具

在调用静态成员时,我通常将c别名用于类型声明和.NET类型

int i = Int32.Parse(s);
这只是个人偏好。

如果你看一下,规则SA1121实际上执行了与你想要的相反的命令,要求你将Int32更改为int。反编译该规则并创建你自己的StyleCop规则来执行相反的命令是相当简单的

这不是自动的,但在您完成初始转换后,您可以将其合并到构建中,然后将任何新的使用标记为错误。

如果您查看,SA1121规则实际上执行了与您希望的相反的命令,即要求您将Int32更改为int。反编译该规则并创建自己的StyleCop规则来执行相反的命令是相当简单的

这不是自动的,但在您完成初始转换后,您可以将其合并到构建中,然后将任何新的使用标记为错误。

使用,以下操作在实践中似乎有效:

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);
}
输出:

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
//
您甚至可以利用工作区功能更新整个解决方案:

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!
使用,以下内容在实践中似乎有效:

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);
}
输出:

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
//
您甚至可以利用工作区功能更新整个解决方案:

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!

我最终写了一个宏来实现这一点

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

我最终写了一个宏来实现这一点

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


就个人而言,我更喜欢前者,但这就是我:-这似乎完全没有必要。你无聊吗?或者你想在你的大学里强制执行这个?我喜欢它们的原因是颜色显示它是一个内置的,使用自定义语法重写器。对我来说似乎是一个编辑问题。如果基本类型使用某种颜色并将其更改为浅蓝色,请在选项中查找。我个人更喜欢前者,但我就是这样:-这似乎完全没有必要。你无聊吗?或者你想在你的大学里强制执行这个?我喜欢它们的原因是颜色显示它是一个内置的,使用自定义语法重写器。对我来说似乎是一个编辑问题。如果基元类型使用某种颜色,请在选项中查找并将其更改为浅蓝色我也这样做了,但很快就遇到了包含类型名称的变量/方法/字段名称的问题,以及像方法签名这样的情况:void Foostring derpIt是一个好主意,可以扩展查找选项并检查匹配大小写和匹配整词复选框。您确切知道匹配整词的功能吗?我从来没有想过。如果您正在查找字符串,它将找不到StringWriter。我也这样做过,但很快就遇到了包含类型名称的变量/方法/字段名的问题,以及像方法签名这样的情况:void Foostring derpIt是一个好主意,可以扩展查找选项并检查匹配大小写和匹配整词复选框。您确切知道匹配整词的功能吗?我从来没有想过。如果你正在寻找字符串,它不会找到StringWriter。非常棒的主意!非常感谢。我会查一查。如何去反编译规则?非常棒的主意!非常感谢。我会查一查的。你怎么去反编译规则呢?