【问题标题】:Fold class fields and constructor parameters in Rider在 Rider 中折叠类字段和构造函数参数
【发布时间】:2021-05-04 01:35:16
【问题描述】:

我在一个 .NET 项目中使用 Rider,该项目有许多注入大量服务并在文件顶部占用大量空间的类,如下所示:

public class MyCoolService: IMyCoolService
{
    private readonly IMyInjectedService1: myInjectedService1;
    private readonly IMyInjectedService2: myInjectedService2;
    private readonly IMyInjectedService3: myInjectedService3;
    private readonly IMyInjectedService4: myInjectedService4;
    private readonly IMyInjectedService5: myInjectedService5;
    private readonly IMyInjectedService6: myInjectedService6;
    private readonly IMyInjectedService7: myInjectedService7;
    private readonly IMyInjectedService8: myInjectedService8;
    private readonly IMyInjectedService9: myInjectedService9;
    private readonly IMyInjectedService10: myInjectedService10;
    private readonly IMyInjectedService11: myInjectedService11;
    private readonly IMyInjectedService12: myInjectedService12;
    private readonly IMyInjectedService13: myInjectedService13;
    private readonly IMyInjectedService14: myInjectedService14;
    private readonly IMyInjectedService15: myInjectedService15;
    private readonly IMyInjectedService16: myInjectedService16;
    private readonly IMyInjectedService17: myInjectedService17;
    private readonly IMyInjectedService18: myInjectedService18;
    private readonly IMyInjectedService19: myInjectedService19;
    private readonly IMyInjectedService20: myInjectedService20;

    public MyCoolService(IMyInjectedService1 myInjectedService1,
        IMyInjectedService2 myInjectedService2, IMyInjectedService3 myInjectedService3,
        IMyInjectedService4 myInjectedService4, IMyInjectedService5 myInjectedService5,
        IMyInjectedService6 myInjectedService6, IMyInjectedService7 myInjectedService7,
        IMyInjectedService8 myInjectedService8, IMyInjectedService9 myInjectedService9,
        IMyInjectedService10 myInjectedService10, IMyInjectedService11 myInjectedService11,
        IMyInjectedService12 myInjectedService12, IMyInjectedService13 myInjectedService13,
        IMyInjectedService14 myInjectedService14, IMyInjectedService15 myInjectedService15,
        IMyInjectedService16 myInjectedService16, IMyInjectedService17 myInjectedService17,
        IMyInjectedService18 myInjectedService18, IMyInjectedService19 myInjectedService19,
        IMyInjectedService20 myInjectedService20)
    {
        this.myInjectedService1 = myInjectedService1;
        this.myInjectedService2 = myInjectedService2;
        this.myInjectedService3 = myInjectedService3;
        this.myInjectedService4 = myInjectedService4;
        this.myInjectedService5 = myInjectedService5;
        this.myInjectedService6 = myInjectedService6;
        this.myInjectedService7 = myInjectedService7;
        this.myInjectedService8 = myInjectedService8;
        this.myInjectedService9 = myInjectedService9;
        this.myInjectedService10 = myInjectedService10;
        this.myInjectedService11 = myInjectedService11;
        this.myInjectedService12 = myInjectedService12;
        this.myInjectedService13 = myInjectedService13;
        this.myInjectedService14 = myInjectedService14;
        this.myInjectedService15 = myInjectedService15;
        this.myInjectedService16 = myInjectedService16;
        this.myInjectedService17 = myInjectedService17;
        this.myInjectedService18 = myInjectedService18;
        this.myInjectedService19 = myInjectedService19;
        this.myInjectedService20 = myInjectedService20;
    }
}

当我浏览代码时,我喜欢使用代码折叠来获得一个类的概览,然后再展开并深入到我想要处理的特定部分。目前 Rider 可以自动折叠隐藏了一些细节的构造函数体:

public class MyCoolService: IMyCoolService
{
    private readonly IMyInjectedService1: myInjectedService1;
    private readonly IMyInjectedService2: myInjectedService2;
    private readonly IMyInjectedService3: myInjectedService3;
    private readonly IMyInjectedService4: myInjectedService4;
    private readonly IMyInjectedService5: myInjectedService5;
    private readonly IMyInjectedService6: myInjectedService6;
    private readonly IMyInjectedService7: myInjectedService7;
    private readonly IMyInjectedService8: myInjectedService8;
    private readonly IMyInjectedService9: myInjectedService9;
    private readonly IMyInjectedService10: myInjectedService10;
    private readonly IMyInjectedService11: myInjectedService11;
    private readonly IMyInjectedService12: myInjectedService12;
    private readonly IMyInjectedService13: myInjectedService13;
    private readonly IMyInjectedService14: myInjectedService14;
    private readonly IMyInjectedService15: myInjectedService15;
    private readonly IMyInjectedService16: myInjectedService16;
    private readonly IMyInjectedService17: myInjectedService17;
    private readonly IMyInjectedService18: myInjectedService18;
    private readonly IMyInjectedService19: myInjectedService19;
    private readonly IMyInjectedService20: myInjectedService20;

    public MyCoolService(IMyInjectedService1 myInjectedService1,
        IMyInjectedService2 myInjectedService2, IMyInjectedService3 myInjectedService3,
        IMyInjectedService4 myInjectedService4, IMyInjectedService5 myInjectedService5,
        IMyInjectedService6 myInjectedService6, IMyInjectedService7 myInjectedService7,
        IMyInjectedService8 myInjectedService8, IMyInjectedService9 myInjectedService9,
        IMyInjectedService10 myInjectedService10, IMyInjectedService11 myInjectedService11,
        IMyInjectedService12 myInjectedService12, IMyInjectedService13 myInjectedService13,
        IMyInjectedService14 myInjectedService14, IMyInjectedService15 myInjectedService15,
        IMyInjectedService16 myInjectedService16, IMyInjectedService17 myInjectedService17,
        IMyInjectedService18 myInjectedService18, IMyInjectedService19 myInjectedService19,
        IMyInjectedService20 myInjectedService20)
    {...}
}

但是,这留下了私有字段和构造函数参数。我最终要做的是使用Ctrl+. 自定义代码折叠来隐藏这些区域(然后我可以在需要时展开它们)。我的问题是每次都是手动过程。有没有办法让 Rider 将这些区域识别为可折叠并自动完成?

public class MyCoolService: IMyCoolService
{
    ...

    public MyCoolService(...)
    {...}
}

【问题讨论】:

  • 如果您需要将 20 个服务注入到一个类中,这表明您需要将该类重构为多个类,因为它可能会尝试做太多事情。那个或所有这些服务都过于简单化了,可以合并在一起。
  • 同意。尽管它是一个大型遗留代码库,并且像这样的重构将是相当大的变化。目前我只是想办法让它更好地工作
  • 我发现Rider lets you define custom foldable regions//<editor-fold desc="description"> cmets。这不是一个理想的解决方案 - 我希望 IDE 自动识别这些区域 - 但它是一个解决方案

标签: c# .net jetbrains-ide rider


【解决方案1】:

理想情况下,您不会将那么多服务注入到一个类中。理想的方法是重构代码,避免有太多依赖。

但是,这可能不是一个简单的选择,这是可以理解的。您可以做的一件事是使用#region 语句包装代码。这告诉 IDE 折叠指定区域中的代码。

以下是如何在示例中使用它的示例

public class MyCoolService: IMyCoolService
{
    #region Injected properties

    private readonly IMyInjectedService1: myInjectedService1;
    private readonly IMyInjectedService2: myInjectedService2;
    private readonly IMyInjectedService3: myInjectedService3;
    private readonly IMyInjectedService4: myInjectedService4;
    private readonly IMyInjectedService5: myInjectedService5;
    private readonly IMyInjectedService6: myInjectedService6;
    private readonly IMyInjectedService7: myInjectedService7;
    private readonly IMyInjectedService8: myInjectedService8;
    private readonly IMyInjectedService9: myInjectedService9;
    private readonly IMyInjectedService10: myInjectedService10;
    private readonly IMyInjectedService11: myInjectedService11;
    private readonly IMyInjectedService12: myInjectedService12;
    private readonly IMyInjectedService13: myInjectedService13;
    private readonly IMyInjectedService14: myInjectedService14;
    private readonly IMyInjectedService15: myInjectedService15;
    private readonly IMyInjectedService16: myInjectedService16;
    private readonly IMyInjectedService17: myInjectedService17;
    private readonly IMyInjectedService18: myInjectedService18;
    private readonly IMyInjectedService19: myInjectedService19;
    private readonly IMyInjectedService20: myInjectedService20;

    #endregion

    public MyCoolService(
        IMyInjectedService1 myInjectedService1,
        IMyInjectedService2 myInjectedService2, IMyInjectedService3 myInjectedService3,
        IMyInjectedService4 myInjectedService4, IMyInjectedService5 myInjectedService5,
        IMyInjectedService6 myInjectedService6, IMyInjectedService7 myInjectedService7,
        IMyInjectedService8 myInjectedService8, IMyInjectedService9 myInjectedService9,
        IMyInjectedService10 myInjectedService10, IMyInjectedService11 myInjectedService11,
        IMyInjectedService12 myInjectedService12, IMyInjectedService13 myInjectedService13,
        IMyInjectedService14 myInjectedService14, IMyInjectedService15 myInjectedService15,
        IMyInjectedService16 myInjectedService16, IMyInjectedService17 myInjectedService17,
        IMyInjectedService18 myInjectedService18, IMyInjectedService19 myInjectedService19,
        IMyInjectedService20 myInjectedService20)
    {

        #region property assignments

        this.myInjectedService1 = myInjectedService1;
        this.myInjectedService2 = myInjectedService2;
        this.myInjectedService3 = myInjectedService3;
        this.myInjectedService4 = myInjectedService4;
        this.myInjectedService5 = myInjectedService5;
        this.myInjectedService6 = myInjectedService6;
        this.myInjectedService7 = myInjectedService7;
        this.myInjectedService8 = myInjectedService8;
        this.myInjectedService9 = myInjectedService9;
        this.myInjectedService10 = myInjectedService10;
        this.myInjectedService11 = myInjectedService11;
        this.myInjectedService12 = myInjectedService12;
        this.myInjectedService13 = myInjectedService13;
        this.myInjectedService14 = myInjectedService14;
        this.myInjectedService15 = myInjectedService15;
        this.myInjectedService16 = myInjectedService16;
        this.myInjectedService17 = myInjectedService17;
        this.myInjectedService18 = myInjectedService18;
        this.myInjectedService19 = myInjectedService19;
        this.myInjectedService20 = myInjectedService20;

        #endregion
    }
}

IDE 将能够折叠构造函数。这就是代码折叠后的样子

【讨论】:

  • 看起来您正在使用 VSCode,但这个答案也适用于 Rider。唯一的区别是我在参数周围放置了一个区域,并且不需要在属性分配周围放置一个区域,因为 Rider 将构造函数主体识别为可折叠区域
【解决方案2】:

虽然我同意 @tejas-parnerkar 的回答,但我想提供另一种观点。如果您必须注入那么多类,则意味着该类试图做的事情太多,即它的职责可能没有正确界定。

如果你的班级有这些方法:

class ChoreRunner
{
    private VacuumCleaner _vacuumCleaner;
    private Sink _sink;
    private WashingMachine _washingMachine;
    private Kitchen _kitchen;
    // ...other dependencies
    
    public Task SweepFloor() {}
    public Task DoDishes() {}
    public Task FeedKids() {}
    public Task DoLaundry() {}
    // ...
}

真正的解决方案是将“上帝”类分解为具有严格约束职责的较小类。

interface IChore
{
    Task Do(); 
}

class SweepFloor: IChore
{
    private VacuumCleaner _vacuum;
    public Task Do() {/* ... */}
}

class WashDishes: IChore
{
    private Sink _sink;
    private IDirtyDishSource _dirtyDishSource;

    // ...
    public Task Do() {/* ... */}
}

class Laundry: IChore
{
    private WashingMachine _washingMachine;
    private Dryer _dryer;
    // ...
    public Task Do() {/* ... */}
}

class FeedKids : IChore
{
    private Kitchen _kitchen;
    private IKidProvider _kidProvider;
    // ...
    public Task Do() {/* ... */}
}

【讨论】:

  • 正如我对@juharr 的评论所说的那样,目前这样的重构不是很实用。我只是想更容易地开始浏览代码:)
猜你喜欢
  • 2021-04-02
  • 2022-11-17
  • 1970-01-01
  • 2012-11-30
  • 2018-02-22
  • 2023-03-25
  • 2017-04-01
  • 2014-11-21
  • 1970-01-01
相关资源
最近更新 更多