Resharper的建议将我的私有方法改为静态方法是一个好建议吗?

9

我最近注意到,当我创建设置传递给它们的对象中几个字段的私有方法时,Resharper会提示可以将该方法设为静态。

以下是我可能拥有的一种大大简化了的方法类型的例子。

private void MakeStatusTheSame(MyClass mc, MySecondClass msc)
{
    mc.Status = msc.Status;
}

当我拥有像这样的一个方法时,Resharper提供了一个建议:该方法可以被设为静态的。
我试图避免将公共方法设为静态的,因为它们会对单元测试造成严重影响...但我不确定是否同样适用于私有方法。
Resharper的建议是一种有效的最佳实践,还是我应该关闭它?

2
公共方法是完全可测试的,如果它们不引起副作用的话。 - Robert Harvey
4个回答

11

我认为这绝对是一个静态方法的最佳候选。它不会改变类的任何属性、字段等。

以下是一个例子:

class MyClass
{
  public static void MakeStatusTheSame(MyClass mc, MySecondClass msc)
  {
     mc.status = msc.status;
  }

  private void MakeStatusTheSame(MySecondClass msc)
  {
    this.status = msc.status;
  }

  private int status;
}

另外,你可以将其作为扩展方法(也可以是静态的):

public static class Extensions
{
  public static MyClass MakeStatusTheSame(this MyClass mc, MySecondClass msc)
  {
    mc.status = msc.status
    return mc; /* make the method chainable */
   }
}

8
冒险说一句不同意的话,我得承认我不喜欢将静态方法和实例方法混合使用,并且我总体上不喜欢使用静态方法。静态方法很难测试、很难重写,也很难维护。我更喜欢将处理Foo对象的所有静态方法放入一个单独的FooUtils类中,或者更好的方式是放入一个名为FooSomethingDoer的单例实例中。
当然,在某些情况下使用静态方法是很有道理的,例如在创建前述的单例、工厂等时。我并不是说所有的静态方法都是纯粹的邪恶;只是尽可能避免使用它们。

我同意你的想法。我只有在有意义的情况下才会将方法设置为静态,而不是仅仅因为我“可以”这样做。 - Josh
1
我同意对于公共(public)、受保护的(protected)和内部(internal)方法进行访问,但不适用于私有(private)方法。网络上有一些关于Utils类是否是代码异味的讨论;我建议小心使用它们。 - TrueWill
同意。将一个方法设为静态的是为了传达与该方法使用相关的信息。将所有东西都设置为静态就毫无意义了。 - Shane Courtrille

7

我觉得如此;看到一个方法是静态的,清晰地表明该方法不应与任何实例成员进行交互。

想象一下调试一个非静态方法并意识到实例没有被触及。这是一个糟糕的迹象,如果没有注释说明函数的作用,你可能会被分散注意力,无法解决真正的问题。


2
+1 表示清楚该方法不应与实例成员进行交互。我希望人们在修改特定代码时调用实例成员的方法之前三思而后行。通过将私有方法标记为静态,如果有人修改代码以使用实例成员,他们会收到编译警告,这至少会让他们思考几秒钟。 - mezoid
刚刚几分钟前,我让R#建议将一个方法设为静态的,结果却遇到了一个编译错误,试图访问一个实例字段。虽然这是第一次发生这种情况,但肯定是有什么地方搞混了。 - ProfK
交互是什么意思?修改值?还是包括读取值? - guiomie
1
@guiomie,任何一个操作都可以。例如,String.IsNullOrEmpty()作为参数使用它所需的数据,而不是使用实例成员值。 - overslacked

4

我通常会按照R#的建议去做。这是一个私有方法,所以(希望)你不会针对它编写单元测试。将其声明为静态方法明确表示它不使用任何实例成员,这使得检查副作用更加容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接