【问题标题】:Static vs non-static class members静态与非静态类成员
【发布时间】:2012-04-13 00:45:45
【问题描述】:

我是 c sharp 和一般编程的新手。我有一个快速的问题——关于静态/非静态变量的最佳实践是什么。

我有一个变量,private int x,它属于 y 类。要访问这个变量,我需要引用 y。但是,如果 x 是静态的,我可以在不引用 y 的情况下访问此变量。

在类 y 中的多个方法将引用此值的情况下,哪种方法最好?

希望这是有道理的,我的问题不是太基本!

非常感谢

【问题讨论】:

  • 最好的方法是让您的代码按预期工作,同时非常具有自我描述性和易于维护。澄清一下:在开发方面,“什么是最好的”没有“正确”答案。

标签: c# oop class object static


【解决方案1】:

最佳做法是避免公共静态。在 OOP 中,类旨在隐藏其成员。 Static 实际上不是 instance 的成员,而是 type 的成员。

如果你正在实现单例模式,静态会派上用场。但话又说回来,它们需要被设为私有并通过公共属性访问。

你需要阅读Static Classes and Static Class Members (C# Programming Guide)。

【讨论】:

  • 这对我来说是新的。为什么要避免静电?
  • 答案很长,不是典型的 Stackoverflow 问题。 静态违背 OOP 和 SOLID 原则。
  • XAML 依赖属性和/或扩展方法等怎么样?我在这里遗漏了一些明显的东西吗?
  • 在某些情况下不能避免静态(例如 public readonly static DateTime DefaultDate = ...;。可变静态字段或可变对象的 readonly statics 应该非常仔细地审查,因为这是一个来源多线程错误。所以总的来说我同意 Aliostad。
  • 史蒂文:你撞到头了!可变的不好但不可变的很好。 Alex:我说的是静态变量而不是方法。我喜欢扩展方法。
【解决方案2】:

您需要将静态变量视为属于类,而不是属于该类的实例。

如果在类的所有实例中该变量都应该相同,请使用静态变量。

如果没有,请使用实例变量。

一般来说,拥有公共静态变量是不好的做法 - 它是一个共享的全局资源,如果您更改它,您需要同步对它的访问。拥有全局状态是您希望尽可能避免的事情。

【讨论】:

    【解决方案3】:

    您的选择取决于您的架构。

    Static 成为 Type 的一部分,其他人则成为该类型的 instance 的一部分。如果您想在同一类型的不同实例之间有一些共享状态(例如),请使用static。如果您希望每个实例都有自己的值,独立于其他实例,请使用 instance 字段。

    顺便说一句,在这两种情况下,请避免像公开的fields 那样公开,而是使用属性。

    【讨论】:

      【解决方案4】:

      一般来说,如果你想拥有一个公共变量,无论是静态的还是实例的,你必须将它包装在一个属性中并像这样公开它。这肯定是您愿意遵循的原则。

      但尽管有其他一些答案,我不能说不要使用静态。在任何情况下,静电都不是你应该避免的魔鬼。只要您保持程序干净且易于维护,您所要做的将决定您是否要使用静态。

      简单地说,而不是用长者的语言,静态代表不属于这个类的任何实例但对它们有影响的东西。生成实例的类中的静态属性的一个示例是一个因子,它应该对类的所有实例都是全局的,以参与在实例内部完成的计算。对于这种情况,在我看来,最好将此因素声明为静态,而不是在每个实例中都有它。尤其是如果这个因素在程序的生命周期中发生变化以影响下一次计算。

      【讨论】:

        【解决方案5】:

        你需要问自己一个问题:为什么我需要 x 是静态的?

        如果将 x 设为静态,则意味着 x 是 A 类的所有对象的一部分,但当 x 不是静态时,则意味着 x 仅是一个对象的一部分。

        一般来说,使用静态字段对于错误跟踪来说很痛苦,但在某些情况下这非常有用。

        我建议你看看使用singelton http://en.wikipedia.org/wiki/Singleton

        【讨论】:

          【解决方案6】:

          嗯,我不能肯定地说哪个更好,因为它们有不同的用途。

          您熟悉面向对象编程吗?在OOP中,静态对象或类的成员可以直接从类中访问,而非静态成员只能从其所属的实例中访问。

          C# 的方法遵循类似的原则。静态方法可以直接从类中访问,而非静态方法(或我喜欢称之为实例方法)必须从实例中访问。这就是为什么需要对实例方法进行实例化,而对于静态方法则不需要,而且不切实际(见下文)。

          在 OOP 中,静态变量用于无法由实例变量存储的值。示例:假设您想计算一个类的实例数?您将如何将其存储在单个实例中?

          这些方法使用类似的原理。它们应该用于在类的实例中执行不切实际的过程。我倾向于将它们用于广泛的过程(不是技术术语),这意味着那些不需要我实例化对象的过程。例如,添加两个参数。 (这种用法可能正确也可能不正确,但我相信它是)

          但是,如果您想添加一个对象的两个属性,则该方法不能是静态的,因为您很快就会意识到,静态方法不能访问类中的实例方法或变量。当然这是有道理的,因为除非被告知,否则静态方法不会知道从类的哪个实例获取这些,因为它不是实例本身的一部分)

          为了不让事情变得更复杂,我将在此停止。如果您有任何误解,请告诉我。

          【讨论】:

            【解决方案7】:

            我完全同意Oded先生的观点:

            如果在类的所有实例中该变量都应该相同,请使用静态变量。

            如果没有,请使用实例变量。

            是的,将static 添加到类成员基本上意味着您可以在没有实例的情况下访问它,并且只能在任何实例之外访问。是的,它变成了一个全局资源,如果你愿意的话,甚至可以变成一个全局变量。

            但我认为这里至少还有另一个 (heavily edited) 好点...

            使用静态成员作为全局变量不符合OOP

            这意味着一旦设置了静态成员,就不能将其作为对象传递。使用 static 作为全局变量越多,unit testing / mocking classes 就越困难。

            有一个解决方案,Singletons。但他们不应该没有warnings!

            另一方面,如果您确定确实需要全局变量,请查看 Toolbox 模式。这是单例模式的一个不为人知的扩展。事实上它是如此的未知,如果你用谷歌搜索它,你不会用那些关键字找到它(工具箱模式)。

            所以提前计划。阅读更多。了解每个选项,以便您做出更好的决定。甚至得到一本书。面向对象编程更多的是应用有助于长远发展的概念,而不仅仅是让事情现在就开始工作。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-05-20
              • 1970-01-01
              • 2012-12-04
              • 1970-01-01
              • 2013-08-25
              • 1970-01-01
              • 2012-10-20
              相关资源
              最近更新 更多