ReSharper 2025.2 Help

降低算法复杂性并促进模块化

几乎每位开发人员都曾遇到过这样的情况:一个复杂的算法被写在一个几乎无法阅读的方法中,并且与类中的其他方法纠缠在一起。 例如,假设您有一个用于求解方程的通用类:

public class EquationSolvers { public static Tuple<double, double> Quadratic(double a, double b, double c) { double disc = b*b - 4*a*c; if (disc < 0) throw new ArgumentException("Cannot solve equation with complex roots"); double sqrt = Math.Sqrt(disc); return new Tuple<double, double>( (-b + sqrt) / (2 * a), (-b - sqrt) / (2 * a)); } // other solvers here }

上述方程求解器是硬编码的,这意味着如果要替换为不同的求解器,您必须手动替换每个实例。 让我们先将其提取到一个单独的类中。 为此,我们使用 移动到另一类型的重构 F6

使用 ReSharper 实现模块化

然后,我们需要指定要将方法移动到的类。 为了更好地分离关注点,我们选择一个名为 QuadraticEquationSolver 的单独类:

使用 ReSharper 实现模块化

现在方法已经被移动了,让我们尝试将判别式提取到一个单独的计算中。 这很简单——我们选择判别式计算并调用 提取方法重构 Control+Alt+M

使用 ReSharper 实现模块化

现在,我们需要做的就是给新方法命名:

使用 ReSharper 实现模块化

完成了:

private static double CalculateDiscriminant(double a, double b, double c) { return b * b - 4 * a * c; }

现在,假设过了一段时间,我们找到了一个更安全的二次方程求解器。 为了将其引入程序,我们首先需要创建一个抽象基类 QuadraticEquationSolverBase。 我们使用 提取超类重构 重构功能,该功能可在 重构 菜单 Control+Shift+R 中找到:

使用 ReSharper 实现模块化

在显示的对话框中,我们可以选择哪些成员将被向上提升。 我们只需要 CalculateDiscriminant 方法:

使用 ReSharper 实现模块化

我们添加了 Calculate() 方法的抽象定义(之前称为 Quadratic() ),并得到了以下基类:

public abstract class QuadraticEquationSolverBase { protected double CalculateDiscriminant(double a, double b, double c) { return b*b - 4*a*c; } public abstract Tuple<double, double> Calculate(double a, double b, double c); }

我们还移除了代码中任何地方的 静态 关键字,假设 QuadraticEquationSolverBase 的实现将由代码中的生命周期管理器处理。 因此,ReSharper 提醒我们在 QuadraticEquationSolver 类中为重命名的 计算 方法添加 重写 关键字:

使用 ReSharper 实现模块化

现在,假设我们找到了一个更安全版本的二次方程求解器。 让我们实现它。 首先,我们在基类上使用 创建派生类型 context action

然后,我们被要求在此类型上实现成员,我们照做了:

最后,我们提供了一个实现,利用了基类的 CalculateDiscriminant() 方法:

class SafeQuadraticEquationSolver : QuadraticEquationSolverBase { public override Tuple<double, double> Calculate(double a, double b, double c) { double disc = CalculateDiscriminant(a, b, c); if (disc < 0) throw new ArgumentException("Cannot solve equation with complex roots"); double q = -0.5*(b + Math.Sign(b)*disc); return new Tuple<double, double> (q/a, c/q); } }

完成了! 现在,二次方程求解器可以轻松使用,其配置和实例化通常由 IoC 容器处理。

最后修改日期: 2025年 9月 27日