静态意味着没有国家

时间:2009-10-27 01:06:26

标签: c# static state

我最近向我的一位同事提出建议,指出我们当前的项目(C#)“服务应该是无状态的,因此是静态的”。

我的同事同意并表示,在我们的项目中,服务(并且应该)确实是无国籍的。然而,我的同事不同意静态意味着没有状态,无状态应该意味着静态。

我的问题是“标记为静态的方法是否意味着它不需要任何状态,并且在大多数情况下,无状态方法应该是静态的”。

13 个答案:

答案 0 :(得分:7)

静态几乎意味着全球化。还有一个实例,在该实例中仍然存在状态,但它是静态实例,这意味着只有一个,所有调用者总是引用那个。

答案 1 :(得分:5)

  

标记为静态暗示的方法   它不需要任何州

1)否。你不能说静态方法暗示它不需要状态,因为静态方法可以访问静态/单例资源。

  

大多数案件应无国籍   方法是静态的

2)是的。不需要状态的方法,因此不需要实例,通常应该是静态的。

答案 2 :(得分:3)

C#中的静态方法可以访问其包含类的静态变量,如果是,则不是无状态的。我已经看到一些令人痛苦的非重入“无状态”静态方法,引发了有趣的竞争条件。

真正无状态的方法确实可以是静态的,通常应该是。

答案 3 :(得分:3)

我觉得无状态 static 相同,因为这是两个不同的世界,这是相当可怕的。无状态意味着没有状态保持,即一个完美的例子是HTTP连接(一旦数据被发送,连接被关闭,并且没有保留内存),我们实际上正在努力尽力保持状态(登录一个国家)。

静态另一方面是用于描述调用方法的方式的术语。在C#中,这意味着可以在没有类实例的情况下调用方法,但类的实例与state不同。还有静态实例,它完全能够维护状态:任何静态成员变量,字段或属性都可以维持状态。静态方法或类也完全能够通过使用内存映射文件,数据库或其他任何东西来维护状态。静态是一种调用约定,仅此而且与无状态无关。

答案 4 :(得分:3)

我认为他的陈述与“民主国家应该使用黄纸选票”一样有意义。

他正在将高级设计概念“无状态服务”与低级技术实现细节“使用静态类”相结合。

无状态服务可以(并且已经)以仅支持静态变量(例如COBOL,RPG)的语言和甚至不支持静态变量的语言(Erlang等)实现。

我很容易想象一个使用静态类实现无状态服务的情况,因为他们在那里并且已经实现了正确的业务逻辑,尽管它通常被认为是优秀的Java编程实践,除非你真的需要,否则不要使用静态类。

他还严重误解了“静态”的含义 - 静态变量是一种在调用之间存储状态的方式 - 因此似乎与“有状态”服务更好地匹配。

答案 5 :(得分:2)

static 是一种语言关键字, state 是一种设计概念。这两件事之间有明显的关系,但它是具体与形而上学的关系,而不是因果关系。静态方法可以引用某些类型的状态信息。

关于无状态方法,这里我们讨论的是不引用类实例的方法,即this指针。将这些方法标记为静态可以提高代码的清晰度,并与最佳实践保持一致。请注意,在这种情况下,我们正在讨论一种特定的“无国籍”,而不是对有状态上下文的使用做出一般性评论。

答案 6 :(得分:1)

静态可以是有状态的。你只需要为所述状态定义静态容器。并且容器在对静态方法的所有调用中共享。

答案 7 :(得分:1)

每个类都有一个类定义结构,其中表示和存储静态字段。该类的每个“实例”都可以访问存储在类定义中的静态字段(数据结构caleld CORINFO_CLASS_STRUCT)。即使已经创建了NO实例,程序集中任何位置的代码都可以使用语法classname.StaticFieldName访问这些静态类级别字段,而根本不需要任何实例。

由于存储在这些静态类级别字段中的值是持久的,因此它们肯定是状态。实际上,它们不仅是可能存在的类的任何实例共享的状态,它们在整个程序集中共享,无论是否已创建任何实例。

更重要的是,因为一旦加载了CORINFO_CLASS_STRUCT类定义,与类的真实实例不同,它就是 从未卸载 直到程序集(或AppDomain)被卸载,因此可以说 更有状态 比在类中定义的任何实例字段更强,因为当实例被垃圾收集时,实例字段会消失。 / p>

有关详细信息,请查看Don Boxes精彩图书CORINFO_CLASS_STRUCT

的{{1}}链接

答案 8 :(得分:1)

对你的问题的简短回答是“不”,static并不意味着“没有国家”。

在参考您的其他评论时,static可用于帮助您实施无状态服务,但仅static是不够的。另一种帮助使无状态的工具/技术是使用不可变数据结构。这(当前)不是C#的强项之一,特别是与F#相比时。

答案 9 :(得分:1)

除了重复所有可以运行的“静态”定义之外,答案是“是”。静态方法可以愉快地修改类本身的状态(通过静态变量表示),并且甚至修改类的实例状态(特别是,当它们传递一个实例或一组实例时)。 但是,大​​多数情况下,在没有状态更改的情况下,您将使用静态方法。最重要的例子是查找或创建实例(工厂方法)。

那就是说,真正的答案是“不”。在现实生活中(例如,通过HTTP进行Web服务,或与​​任何类型的Orb交互),服务从不使用实际的静态方法公开其服务方法。您通常调用静态方法来获取服务的实例(或服务工厂的实例,从中获取实例!),然后使用它。 这是因为您的服务代理在内部需要跟踪它的位置。因此,虽然你的方法对你来说似乎没有状态,但实际上并非如此。

希望这不会太混乱:)。

答案 10 :(得分:1)

静态类不是无状态的。它仍然可以有变量,虽然是静态的,但却具有状态。

没有任何类级变量的静态类是无状态的。它没有数据。

答案 11 :(得分:0)

这通常是正确的。但是,您可以使用静态变量,这允许静态方法具有状态。例如,拿这个FooBarFactory类:

class FooBarFactory
{
    private static _id = 0;
    public FooBar MakeAFooBar()
    {
        FooBar foo = new FooBar();
        foo.ID = _id;
        _id++;
    }
}
class FooBar
{
    public int ID {get;set;}
}

在这种情况下,你的静态方法具有最小的状态,但它(可能)是必要的。

答案 12 :(得分:-1)

如果您想要一个具有状态的单个实例,请使用单例模式;它使意图明确表明你正在使用单一事件。

然后,我会将所有静态类和方法视为无状态。它只是有助于保持理智。