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

时间:2011-04-23 23:37:55

标签: c# vb.net programming-languages static

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

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

违反了吗?

编辑:

我有一个名为 p 的私有变量,它是一个整数。它在整个程序中从未读过,所以它不会影响任何程序流程。

是否违反“无副作用”?:

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

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

3 个答案:

答案 0 :(得分:2)

当你说"他们",你在引用谁?

无论如何,继续前进。你所呈现的方法完全没问题 - 如果这是你想要的,那就OK。不用担心。

类似地,静态类具有一些静态状态是完全有效的。同样,可能会在某些时候需要它。

值得注意的是

static class A
{
    private static int x = InitX();

    static A()
    {
        Console.WriteLine("A()");
    }

    private static int InitX()
    {
        Console.out.WriteLine("InitX()");
        return 0;
    }
    ...
}

如果你沿着这些方向使用某些东西,那么你很容易对调用静态构造函数和何时调用InitX()感到困惑。如果您在本例中出现了一些副作用/状态变化,那么这将是不好的做法。

但就你的实际问题而言,那种状态变化和副作用都很好。

修改

看看你的第二个例子,并按照规定精确地遵守规则,然后,是的,你违反了它。

但是...

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

答案 1 :(得分:1)

static成员的副作用意味着它会更改其容器class中某些其他成员的值。您案件中的static成员不会影响其class的其他成员,也不会违反您提到的句子。


修改

在第二个示例中,您通过编辑问题添加了违反该问题的内容。

答案 2 :(得分:1)

静态类的方法更改传递给它们的对象的状态是完全可以接受的。实际上,这是非函数静态方法的主要用途(因为不改变某些状态的非函数方法将毫无用处)。

要避免的模式是具有静态类,其中方法具有副作用,这些副作用不限于传入的对象或它们引用的对象。例如,假设有一个刺绣绘图类,它具有选择刺绣模块的功能,以及缩放,平移或旋转未来的图形操作。如果多个例程期望进行一些绘制,则可能难以防止由一个例程完成的设备选择或转换影响其他例程。有两种常用方法可以解决此问题:

  1. 让所有静态图形例程接受一个参数,该参数将保存当前设备和世界变换的句柄。
  2. 拥有一个包含设备句柄和世界变换的非静态类,并让它公开一整套图形方法。

在许多情况下,最好的解决方案是让一个类使用第二种方法作为其外部接口,但可能在内部使用第一种方法。关于单一责任原则,第一种方法稍好一些,但从外部呼叫的角度来看,使用类方法通常比使用静态方法更好。