【问题标题】:In Visual Studio, is there a way to sort private methods by usage?在 Visual Studio 中,有没有办法按使用对私有方法进行排序?
【发布时间】:2017-03-12 10:42:34
【问题描述】:

在 Visual Studio 中,无论是否有扩展,有没有一种方法可以根据使用顺序(它们在调用堆栈中的位置)自动对类中的私有方法进行排序?

例如考虑以下类:

public class MyClass
{
    public void MyMethod()
    {
        TestC();
    }

    private void TestA()
    {
        TestB();
    }

    private void TestB()
    {
        Console.WriteLine("Hello");
    }

    private void TestC()
    {
        TestA();
    }
}

这个类中的公共方法是MyMethod,它调用TestC,它调用TestA,它又调用TestB。我想(自动)按此顺序对这些方法进行排序,以便类看起来像这样:

public class MyClass
{
    public void MyMethod()
    {
        TestC();
    }

    private void TestC()
    {
        TestA();
    }

    private void TestA()
    {
        TestB();
    }

    private void TestB()
    {
        Console.WriteLine("Hello");
    }
}

我需要能够选择一个类,请求这样的方法排序,并让方法自动排序。即,我不想手动对这些方法进行排序。

我知道有一些细微差别。例如,可能有一个私有方法从调用堆栈中位于两个不同级别的两个方法调用。我想在这种情况下,考虑与公共方法的最小(调用堆栈)距离是有意义的。

更新:

以这种方式对方法进行排序的想法来自 Robert C. Martin 的 Clean Code book。在第 3 章中,定义了 Stepdown 规则,它讨论了让高级函数出现在低级函数之前。

在google上快速搜索降级规则,我发现了一个netbeans插件:http://plugins.netbeans.org/plugin/58863/stepdownruleplugin

我猜它的功能与我需要的类似,但适用于 netbeans。

【问题讨论】:

  • Resharper 声称能够以各种方式对方法进行排序。
  • @RawN,我试图通过 Resharper 找到一种方法,但我找不到任何方法。
  • 我怀疑你会发现这个开箱即用。您当然可以使用 roslyn (github.com/dotnet/roslyn) 对其进行编码,它可以解析代码、确定调用层次结构等。
  • @SimonMourier,我希望有人已经这样做了。
  • @YacoubMassad 请问您为什么要这样做?只是好奇

标签: c# visual-studio refactoring


【解决方案1】:

以下是其他没有人引用过的产品,它们可以通过友好的请求添加功能:

自己写这个并不难。新的 Visual Studio VSIX 项目 模板在 VS2015 设置中可用,如果在 (File > New > Project.. Visual C# > Extensibility) 下找不到它们,只需修改安装 (cmd > appwiz.cpl > VS2015 更改/修改)。

好消息是 CodeMaid 项目是开源的,包含您需要重新排序代码块的大部分代码和逻辑。

您需要的另一件事是调用堆栈,我们的一位乐于助人的 Stackoverflow 同事在这里提供了代码:How to get stack trace of a running process from within a Visual Studio add-in?

鉴于这是一个赏金,您可能期待一个完整的解决方案,抱歉,我现在没有时间为您编写代码,但如果您遇到任何问题,我很乐意帮助您。在 cmets 中告诉我。

为了快速启动和运行,我个人只需复制此 Visual Studio 扩展中的代码,并用 Re-Ordering by Call Stack:Debug Single Thread 替换内脏。

【讨论】:

  • 谢谢。所以似乎没有现成的解决方案,我必须自己创建一个,或者在类似的工具上构建。
  • 是的,或者您可以向我提到的工具的作者之一提出功能请求。您知道该怎么做,但是当我想按调用顺序查看代码时,我只使用 Debug/Code Canvas 或 Bubble Debugging,这是一个比较 blogs.msdn.microsoft.com/kaelr/2012/03/10/… 尝试一下,这对您来说可能比重新排序代码更好,因为通常有许多不同的分支/路径/重用,一个顺序并不总是正确的。
【解决方案2】:

ReSharper 插件“Greenkeeper”完成了这项工作:

https://bitbucket.org/denniskniep/greenkeeper

插件可以对“newspapermode”中的方法进行排序:重要代码在前,细节在底部。报纸模式的行为与“降级规则”相同。

https://bitbucket.org/denniskniep/greenkeeper/wiki/SortingDeclarations

【讨论】:

  • 这正是我想要的。谢谢。这个插件适用于 Resharper 8.2,我已经测试过了。我将尝试使其与更高版本的 Resharper 一起使用。
  • 没有出现在 Resharper 2017 的列表中 :(
  • 对于 R#2017 的插件应该是不必要的。它内置在 R# 中。在此处检查接受的答案:stackoverflow.com/questions/1509244/…(虽然我自己还没有尝试过......)
【解决方案3】:

简短的回答是“否” 看到原因很简单,因为大多数开发人员试图编写易于阅读的代码。如果我需要对 TestB 进行更新并查看代码,我希望 TestB 在 TestA 之后和 TestC 之前定义。然后,您还要考虑类的已定义字段以及使用 get/set 方法设置和获取已定义字段的值。

下面的代码显示了 2 个类。第一个类是在我个人用于可读性的布局中,如果另一个开发人员需要更新他们不会浪费时间寻找代码的代码。第二类按照您希望它们重新排列的方式进行。

            public class MyClass
            {
                private string _HelloWorld;
                public string HelloWorld
                {
                    get {return _HelloWorld;}
                    set {_HelloWorld = value;}
                }

                public void MyMethod
                {
                    TestC();
                }

                public void TestA()
                {
                    TestB();
                }

                public void TestB()
                {
                    Console.WriteLine(HelloWorld);
                }

                public void TestC()
                {
                    TestA();
                }

            }

            public class MyClass2
            {
                private string _HelloWorld;

                public void MyMethod
                {
                    TestC();
                }

                public void TestC()
                {
                    TestA();
                }

                public void TestA()
                {
                    TestB();
                }

                public void TestB()
                {
                    Console.WriteLine(HelloWorld);
                }

                public string HelloWorld
                {
                    get {return _HelloWorld;}
                    set {_HelloWorld = value;}
                }
            }

【讨论】:

  • 按照我想要的方式对方法进行排序有一些可读性的好处。主要是先了解高层的方法,再往下看低层的方法等等。
  • 这是一个有效的观点。这完全取决于与您合作的团队。
【解决方案4】:

如果您想手动触发该逻辑并使用 vs 2015,您可以创建一个将使用 Roslyn 的 Visual Studio CodeFix。 见:Build CodeFix ex

你应该做的步骤是:

  1. 创建 CodeFix 项目
  2. CodeFix 的逻辑,使用 Roslyn,将分析文档中的所有方法,并在方法之间创建依赖关系图。比它会改变顺序并将代码重写到文档中
  3. 安装 CodeFix,作为分析器,并将其用于您想要的每个 Visual Studio 文档

【讨论】:

  • 虽然这可行,但问题要求现有解决方案(如果有)。我希望 Visual Studio 的生产力工具之一已经具有此功能。
【解决方案5】:

我不知道是否可以在 Visual Studio 中本地执行此操作。但是,我认为最好的方法是使用 ReSharper(Visual Studio 扩展)来执行此操作。

它提供了至少两个想到的选项:

1) 将File and Type Layout 首选项与模式一起使用,

2) 使用“文件结构”窗口(如果要重新排序的类没有太多方法,这可能是最快的方法)。你可以check it out here.

希望对您有所帮助。

【讨论】:

  • 我真的无法理解你的回答。您说您不知道执行此操作的扩展程序,但随后您提供了一些选项。这些选项有什么用?
  • 很抱歉给您带来了困惑。我所指的选项由 Visual Studio 扩展 ReSharper 提供。我已经为每个不同的选项提供了链接,可以让您轻松更改文件中方法的顺序。其中一个选项使用“文件结构”窗口,通过成员变量、属性和方法向您显示文件的结构。从那里,您可以使用鼠标以您想要的任何顺序拖放它们,您将在文件中以新顺序看到方法。
  • 我希望将这些方法作为重构选项自动排序(当然是根据需要),而不是手动排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
相关资源
最近更新 更多