c# vb:当他们说静态类不应该有状态

本文关键字:不应该 状态 静态类 他们说 vb | 更新日期: 2023-09-27 17:52:17

当他们说静态类不应该有状态/副作用时,是不是意味着:

    static void F(Human h)
    {
        h.Name = "asd";
    }

违反了它?

编辑:

我有一个私有变量,现在叫做p,它是一个整数。在整个程序中都不会读取它,因此它不会影响任何程序流程。

这违反了"无副作用"吗?:

int p;
static void F(Human h)
    {
        p=123;
        h.Name = "asd";
    }

在这种情况下,输入和输出仍然是相同的。

c# vb:当他们说静态类不应该有状态

当你说"他们"时,你指的是谁?

不管怎样,继续。像您所展示的这种方法是完全可以的——如果这是您想要它做的,那么没问题。不用担心。

同样,静态类具有某种静态状态是完全有效的。同样,你可能会在某个时候需要它。

真正需要注意的是像

这样的东西
static class A
{
    private static int x = InitX();
    static A()
    {
        Console.WriteLine("A()");
    }
    private static int InitX()
    {
        Console.out.WriteLine("InitX()");
        return 0;
    }
    ...
}

如果您使用这些行,那么您很容易混淆何时调用静态构造函数以及何时调用InitX()。如果你有一些副作用/状态改变发生在这个例子中,那么这将是一个糟糕的做法。

但就你的实际问题而言,这种状态变化和副作用是没有问题的。

编辑

看看你的第二个例子,并完全按照它所说的去做,那么,是的,你违反了它。

但是…

不要让那个规则阻止你做这样的事情。它在某些情况下非常有用,例如,当一个方法进行密集计算时,记忆是降低性能成本的一种简单方法。虽然记忆在技术上具有状态和副作用,但对于每个输入,输出总是相同的,这才是真正重要的。

static成员的副作用是指它改变了其容器class中其他成员的值。在你的案例中,static成员不影响class的其他成员,它没有违反你提到的句子。


编辑

在第二个例子中,通过编辑你的问题,你违反了它。

静态类的方法完全可以改变传递给它们的对象的状态。事实上,这是非函数静态方法的主要用途(因为不改变某些东西的状态的非函数方法是相当无用的)。

要避免的模式是使用静态类,其中方法的副作用不限于传入的对象或由它们引用的对象。例如,假设有一个刺绣绘图类,它具有选择刺绣模块的功能,以及缩放、翻译或旋转未来的图形操作。如果多个例程期望进行一些绘图,则很难防止由一个例程完成的设备选择或转换影响其他例程。有两种常见的方法可以解决这个问题:
  1. 让所有静态图形例程接受一个参数,该参数将持有当前设备和世界转换的句柄。有一个非静态类,它包含一个设备句柄和世界变换,并让它公开一套完整的图形方法。
在许多情况下,最好的解决方案是让一个类在其外部接口使用第二种方法,但可能在内部使用第一种方法。就单一职责原则而言,第一种方法稍好一些,但从外部调用的角度来看,使用类方法通常比使用静态方法更好。