【问题标题】:In which case shouldn't I use static members in a class?在哪种情况下我不应该在类中使用静态成员?
【发布时间】:2013-04-12 06:01:00
【问题描述】:

我不得不问这个问题,因为我觉得只有经验丰富的程序员才能知道类中静态成员的优缺点。我读过解释静态成员的书籍,根据我的观点,我也在我的项目中使用了许多静态成员。

据我了解,如果在我的项目中某个类只使用了 1 次,我的意思是不需要创建一些或多个实例,我应该将其所有成员设为静态,尤其是静态方法。这是真的?这还有另一个好处,因为可以轻松地调用静态成员,而无需创建新实例或在我们的类之间传递实例。

在我的项目中使用静态成员并没有告诉我它有什么问题,我的项目似乎运行正常,当然我并不是说我喜欢使用静态成员并经常随机使用它(正如我解释我的观点以上观点)。我认为静态成员(我不知道)可能有一些优点和缺点,我想从你的经验中知道。请与我分享。
谢谢!

【问题讨论】:

  • 你应该换个方式问这个问题:我什么时候应该使用静态成员?一般来说,除非必须,否则不要使用静态方法。
  • 我的问题集中在寻找使用静态时不好的东西,而不是寻找使用静态时好的东西。同样的想法,我一般不使用静态,但在某些情况下我必须使用它来保持我的代码干净,即使在某些情况下我不知道如果打算使用我的类应该使用什么名称它作为实例,所以我只是称它为任何名称,如“General”、“Misc”、“Tools”……并使其所有成员静态。谢谢。
  • @KingKing ~"在我的项目中只使用了 1 次的一些类"。听起来你需要一个单身人士!

标签: c# .net static


【解决方案1】:

查看以下帖子:

据我了解,如果在我的项目中某个类只使用了 1 次,我的意思是不需要创建一些或多个实例,我应该将其所有成员设为静态,尤其是静态方法。这是真的吗?

这取决于。如果您想在整个应用程序中全局访问静态类(即实用程序类、辅助函数等),我相信静态类是很好的选择。

使用静态类来包含与 特定对象。例如,创建一个 一组不作用于实例数据且不关联的方法 到代码中的特定对象。您可以使用静态类 持有这些方法。

请记住,声明一个静态类允许它在应用程序的整个生命周期内都留在内存中。这意味着如果静态类只使用一次,即使不再需要/将再次使用,它仍将保留在内存中。相反,如果该类只使用一次,则最好创建一个常规类实例,以便在您使用完之后进行 GC 清理。

【讨论】:

  • 当我打算在其他项目中重用我的类时,我不会使用静态,我使用静态的大多数情况是当我打算在特定项目中本地使用它们时(不用于重用),请一些方法全局且易于在整个项目中访问,我关心的是静态成员是否存在性能或内存问题,实际上我使用静态方法比静态变量更多,在这种情况下内存问题不会真的没关系,不是吗?感谢分享好的链接。
【解决方案2】:

据我了解,如果在我的项目中某个类只使用了 1 次,我的意思是不需要创建一些或多个实例,我应该将其所有成员设为静态,尤其是静态方法。这是真的吗?

它可以——有时你想要一个实例,但它不能是静态的,因为它实现了一个接口——在这种情况下你会使用单例模式。

静态方法很有用,如果您的类不包含状态,那么作为静态类的可能性应该没问题。

【讨论】:

  • 是的,保存状态应该实例化而不是声明静态成员,但是我不喜欢使用包含大内存的静态变量,我只关心使用静态方法,它们是一些用于处理的实用程序数据......在全局范围内应用,如果使用实例,我必须在我的类中声明相当多的实例,这会使我的代码变得复杂,而且我还注意到需要仔细使用静态的多线程任务。感谢您的分享。
  • @KingKing 请考虑使用句点将您的评论分成句子。在这里阅读您的帖子的人将很难理解您想说什么。
【解决方案3】:

我对静态的主要问题是它使多态性变得非常困难(在运行时将一件事替换为另一件事)。您经常想要这样做的地方是在编写测​​试时,我想用 MockFileManager 替换 FileManager 类。如果我使用的是非静态类,我只使用接口来实现多态性,希望我使用 IoC 模式并且我可以传入我的模拟实现来代替真实的实现(耶多态性!)。

但是,如果我的 FileManager 类都是静态的,那么很难用其他动态替换它。

注意:有代码分析规则告诉您出于性能原因将事物设为静态。我关闭了这些规则。

【讨论】:

  • 我认为一旦我们决定使用静态,我们就将其视为某种实用程序(如 P/Invoke 函数),它需要传入一些对象并处理并给出结果,它用于静态方法,对于静态变量,我对使用它们并不感兴趣,除非它确实需要。谢谢。
  • 是的,但是如果您使用实际对象而不是静态方法,您有机会在运行时将其替换为 Mock 对象,例如用于单元测试。有时我可能只想测试一个特定的类,而不是它使用的所有辅助方法。特别是如果其中一些辅助方法涉及昂贵的资源,例如文件系统、网络、数据库等。我想重点是,你可以用静态方法做的所有事情都可以用实例方法和 more。如果您使用 IoC,则创建实例并没有真正的负担,因为它们只是由容器注入。
  • @DylanSmith 哪些代码分析规则告诉您将事物设为静态?我从没见过。
  • CA1822 将成员标记为静态:msdn.microsoft.com/en-us/library/ms245046.aspx
【解决方案4】:

引用someone who can explain it way better than me

滥用静态类可以被认为是不好的做法。但是任何语言功能的滥用也是如此。

我没有区分只有静态方法的非静态类和静态类。它们实际上是相同的,除了静态类允许编译器强制执行开发人员的意图(不实例化此类,访问其功能的便捷语法等)。

“Helper”类的泛滥可能会给您带来麻烦(设计、可维护性、可读性、可发现性、其他能力……)。这里没有争论。但是你能说“帮助者”类是不合适的吗?我怀疑。

确实,负责任地使用静态类可以为您的代码带来很多好处:

Enumerable 静态类提供了一组我们大多数人都喜欢的扩展方法。它们是一组逻辑功能/业务逻辑,与任何特定类型的实例无关。 环境/上下文提供的服务:例如日志记录、配置(有时) 其他(我暂时想不到:)) 所以不,一般来说,这不是坏习惯。明智地使用它们...

至于我自己,当我需要使用它们时,我会使用它们,这是否看起来是一种不好的做法并不重要。

经验法则?如果你知道为什么应该使用静态并且可以解释它,那么你应该使用它。

【讨论】:

  • 那句话来自...?
  • 完全忘记了链接-_-
  • 感谢您的分享,甚至有人说它是邪恶的,我不想一直遵循 OOP 规则,明智地使用静态是我的选择。
  • @KingKing 也是一个明智的选择。它的发明是为了让我们可以使用它:) 在不知道为什么或如何使用它的人手中很危险 :)
  • 是的,明智的选择会让它比实例类更有效。谢谢。
猜你喜欢
  • 2016-03-15
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 2010-09-05
相关资源
最近更新 更多