所以我的问题是:
我有一个带有静态方法的静态类,称为:
static class A() {
public static MethodA() { }
}
并且我得到了另一个将多次调用静态类的MethodA()的类:
static class B() {
public static MethodB1() {
MethodA()
}
public static MethodB2() {
MethodA()
}
public static MethodB3() {
MethodA()
}
public static MethodB4() {
MethodA()
}
}
这是正确的方法还是我应该这样做(调用内部函数,这是对静态方法的唯一引用):
static class C() {
public static MethodC1() {
StaticCaller()
}
public static MethodC2() {
StaticCaller()
}
public static MethodC3() {
StaticCaller()
}
public static StaticCaller() {
MethodA()
}
}
我想出这是一个设计或哲学问题,但是有没有技术优势,例如可维护或可伸缩的代码?
编辑:甚至性能改进?
这被认为是基于意见的,因为两种方法都有其各自的优势。 SO上的许多开发人员都有他们自己的偏好,因此要在不放弃意见的情况下进行回答就很有挑战性。在类B中,每个调用都直接转到方法A,而在类C中,该调用首先必须经过本地方法,然后才能转到方法A。此额外步骤可以被认为是多余的,因此,类B是首选的。但是,无论出于何种原因,您都可能不得不将尚未实现的类的调用从方法A更改为方法D。在这种情况下,您必须在B类中更改四个方法,而在C类中仅更改一个。因此,C类更易于维护和调整。因此,两者都有其优点和缺点,并且B类的性能提升很小。 (字面上的时钟滴答声!)因此,总的来说,它并不重要,因此我的建议是选择最适合开发人员阅读的解决方案。这意味着添加注释,使用正确的格式,使用清晰的方法名称,并尝试避免重复自己!后面的评论意味着B类和C类都是不好的做法,就像每个类is repeating a call to some method一样。您应该重新考虑将这些方法重塑为单个方法。这可能很棘手,因为这些方法可能有很多差异。
Wim十个Brink写下了我想要的答案,所以充其量我可以对他说的话做补充:
我讨厌使用静力学。用一个静态调用替换另一个静态调用是很痛苦的。因此,我更喜欢C。它易于更换。
但是我实际上还有两个可能值得考虑的选项:
1st
当我讨厌静态变量时,我尽量避免编写它们。如果我需要像这样的东西并且它有任何非常量字段,则不会将其设为静态。相反,我将其设置为需要实例的普通类。然后创建一个静态类,该类接受此类的实例。听起来不像是这样的差异,而是替换为:
static staticsProvider SP = new ImplementationA();
with
static staticsProvider SP = new ImpelentationB();
允许快速交换。同样,如果您需要两个或多个不同的实例来处理不同的代码段(SP1和SP2),那么现在这只是一个附加的静态字段和实例。这些是静态处理的两个重要问题。而且您仍然可以在类或函数范围内使用实例。
WPF的方式是“如果无法更改,请将其包装成可以更改的内容”。那么选项D:
//I am not a static
public class D{
//I am not either
public void MethodA(){
//But I do call one for you
A.MethodA();
}
}
然后您可以创建一个静态字段:
static public D SP = new D();
如果您需要更多的静态提供者,则?做另一个领域。是否需要其他实现?从D
中提取接口(实际上是VS IDE选项)或创建抽象基类。将变量更改为所述基类/接口。然后创建一个类D2,从您刚创建的类继承/实现。
不想在运行时更改它吗? const或只读修饰符。但是实际上,在运行时交换实例的能力可能是一项功能。
第二
而不是尝试减少对static的调用,如何减少MethodBX和MethodCX的版本呢?
通过使用委托,您可以将“ beforeStatic”和“ afterStatic”部分的代码作为函数来提交。
然而,这仅建议非常小的差异。如果您的差异很大,则为每个调用编写两个大的委托将使它的可管理性降低,然后只需编写现在获得的多重函数即可。
函数调用开销
调用函数会产生成本。实际上,CPU必须进行跳转。跳动仍然是可以衡量成本的事情。总的来说,它可能不会成熟-我们已经超出了限制CPU周期的时间。另外,它可能会自动避免:
本地C ++具有inline编译器提示。
Afaik .NET不允许此控件。但是它确实具有JiT和编译器优化。那些完全可以自动为您内联。对于这样的功能:
public static StaticCaller() {
MethodA();
}
让我说,如果要内嵌any函数,则将看起来像这样的[[have放在列表顶部。