0

只是一个简单的问题:

我读过一个类在不修改其实例时应设为静态。因此,如果我有一个名为 Account 的类,并且它具有诸如 Id、Duration 等属性并且这些属性不会被该类修改,那么可以将其设为静态,否则它应该保持静态。

这(实例本身是否通过其属性发生变异)如何影响静态/实例决策?

此外,如果一个类接受大量参数(比如这个 Account 类,坚持我们的类比),但不修改实例(因此没有 Account 变量更改 - 没有像 Account.x = y // 其中 y 来自另一个类) ,我认为这仍然可以设为静态?所以问题不是参数或它们来自哪里,而是它们做了什么?

如果它是一个属性,则与决定是否将字段设为静态时适用相同的原则(例如,如果该字段保存的数据获取成本很高,那么让一个字段保存它 - 静态 - 如果我错了,请纠正我)。

我注意到 C# 上的静态方法有超过 100 个线程(这属于静态方法,因为它正在处理参数),我将阅读所有这些,因为有很好的问题和很好的答案。

谢谢

4

7 回答 7

6

听起来您希望使该类不可变,而不是静态的?

下面是 C# 3 中对静态类的定义,简而言之:“一个类可以标记为静态,表明它必须仅由静态成员组成,不能被子类化。System.Console 和 System.Math 类是很好的例子静态类。”

对于帐户,我假设您希望系统中的每个帐户都有一个单独的帐户实例。所以我认为你不希望它是静态的。

于 2009-10-01T23:58:06.923 回答
3

看起来您在询问方法和类,所以您有 2 个问题。

方法很简单。如果我正在实现工厂模式;我使用静态方法。如果我希望能够在没有类实例的情况下使用该方法以提高可读性(想想 LogIt() 之类的实用方法;我使用静态方法。

我使用一个静态类(我自己写的)大约和我中彩票一样频繁。所以如果你赢了很多,那就继续用一个很多。说真的,在服务器环境中,线程/并发问题会以各种极其缓慢和痛苦的方式杀死你。

于 2009-10-02T00:05:29.077 回答
2

如果属性没有被类或其他任何东西修改,则将它们设为静态只读或 const 字段,仅使用 getter 属性。这与任何特定方法是否为静态无关。

编辑:非静态类是对象的“模板”,您可以通过基于该模板创建(新)实例来“使用”它。静态类只是方法(函数)的组织“桶”,这些方法(函数)是自包含的代码片段,通常仅对其传入的参数进行操作。(以及任何其他全局范围的变量)

于 2009-10-01T23:56:32.683 回答
2

静态类仅包含静态成员方法和静态成员变量/数据。静态数据可以是公共的也可以是私有的,但只有一个数据副本并且它实际上是全局的(尽管访问范围可能有限制)。静态方法可以访问私有静态数据 - 通常以缓冲区或初始化程序或单例资源的控制块的形式。

通常,只有静态方法(没有数据)的静态类用于不维护内部状态的方法/函数库。还有扩展方法。这些在必要时通常被认为是必要的,但没有任何特别特殊的方式。

如果(静态,当然,在静态类中没有非静态数据)数据被添加到静态类,函数通常不会自动重入或线程安全 - 即在不同线程上对同一函数的两次调用可能相互踩踏,或者如果一个函数接受回调/委托或类似的,并最终调用同一个函数,而先前调用同一函数正在进行中。

仅使用静态类和静态方法,大多数 OO 语言有效地折叠为更接近于 C 或 Pascal 等传统过程语言的语言,而无需创建任何结构和函数指针。

于 2009-10-02T00:06:25.423 回答
1

正如 Abby Fichtner 指出的那样,不可变类通常是一件好事。

静态类通常不是好东西。除了 DancesWithBamboo 指出的线程问题之外,如果类不是不可变的,您正在处理全局数据。曾经尝试调试具有大量全局变量的程序吗?

另一个问题是可测试性。您最终可能会得到许多与静态类耦合的类。为了单元测试的目的,很难打破这种耦合。静态方法总是会被调用。

单身人士只不过是羊皮中的全球数据。它们遭受与静态类和全局变量相同的问题。

静态类有有效的用例(想到扩展方法)。即使是单身人士也有自己的位置。但在实施之前请仔细考虑。

于 2009-10-02T01:27:08.177 回答
0

我不确定我是否完全理解你想要做什么,但这里有一些想法:

1)你不能(至少直接)实例化一个静态类,所以你不能创建一个静态类的对象。在您的示例中,您将永远无法创建帐户的实例。这是你想要的吗?

2)静态类不能有实例变量,它只能包含静态变量,因此在您的示例中,您拥有的所有属性(例如 ID、持续时间)都必须是静态的(不建议用于帐户)

3) 费用:如果您需要共享昂贵的资源,创建一个静态变量使您能够实现单例模式,因为静态变量在该类型的所有实例之间共享,通常这是只读的并实例化一次。像这样的东西:

public class Singleton
{
    private static Singleton _instance = new Singleton();

    private Singleton() {}

    public static Singleton Instance {
        get {
                return _instance;
        }
    }
}

4)您似乎正在寻找不变性,您可以使用结构来实现轻量级对象。

希望这能提供一些指导

于 2009-10-02T00:06:25.580 回答
-2

我不是专家,但我的理解是,如果一个属性没有改变,它应该是一个常量,而不是静态的。

根据我的经验,静态用于表示应用程序中仅存在一个值实例,并且在 OOP 设计中不鼓励使用,尽管它是必要的特性。

如果您有一个类 Account 具有永远不会更改的属性,那么您正在查看的是不可变类的单例实例。您可以使用 static 关键字进行开发,以强制仅实例化 Account 类的 1 个实例,或者将 Properties 声明为常量。

如果您有很多需要静态的方法,那么您本质上是在将程序设计为非面向对象的。到那时,最好决定使用非 OO 编程语言。

我特别鄙视静态,因为如果您有一个多线程应用程序,它是一个主要问题。

于 2009-10-01T23:55:10.610 回答