【问题标题】:Private Static Members inside a Static Class... Good idea?静态类中的私有静态成员......好主意吗?
【发布时间】:2014-11-03 02:08:16
【问题描述】:

我创建了一个包含私有静态成员的静态类。我的所有静态类方法都可以访问该私有静态成员。

这发生在我没有真正注意的时候,但后来我意识到我做了什么,而且——有趣的是——它似乎在我的应用程序中运行良好。尽管如此,这似乎是一件愚蠢的事情(来自 C++),所以我一直在寻找更多关于这是否真的应该可行和/或它是否被认为是好的或坏的做法的信息,但我还没有真正找到任何关于在 C# 中的静态类中创建私有静态成员的信息。

似乎我的静态类中的静态方法有一个隐式的“this”变量(因为我也可以调用其他方法而无需使用类名完全限定它们),这对我来说很奇怪。

我希望你们中的一些人可能对这是否是一个好主意以及为什么 C# 使这成为可能有一些想法。

班级:

public static class ControlHighlighter
{
    private static Panel highlightPanel = null;

    public static void Highlight(Control control = null, int thickness = 1)
    {
        RemoveHighlight();

        if (control != null)
        {
            if (control.Parent != null)
            {
                highlightPanel = new Panel();
                control.Parent.Controls.Add(highlightPanel);
                highlightPanel.Location = new Point(control.Location.X - thickness,
                                                    control.Location.Y - thickness);
                highlightPanel.Size = new Size(control.Size.Width + (2 * thickness),
                                               control.Size.Height + (2 * thickness));
                highlightPanel.SendToBack();
                highlightPanel.BackColor = SystemColors.Highlight;
            }
        }
    }

    public static void RemoveHighlight()
    {
        if (highlightPanel != null)
        {
            highlightPanel.Dispose();
            highlightPanel = null;
        }
    }
}

【问题讨论】:

  • 那么为什么你认为不可能做到这一点?
  • 这个问题似乎跑题了,因为它是关于代码审查的,属于codereview.stackexchange.com
  • 不太确定是否需要存储对此面板的引用,因为它将位于对象的控制列表中,因此只需找到它即可。考虑使用扩展而不是使用私有静态成员。

标签: c# static


【解决方案1】:

一般来说,在静态类(甚至在非静态类)中拥有私有静态成员并没有什么问题。但是,它们确实带来了一些潜在的问题:当您的应用程序是多线程的时,这些静态成员在所有线程之间共享,因此您必须在它们周围应用锁定。

由于您永远不知道是否需要使应用程序成为多线程的,因此最好将静态变量的数量保持在最低限度 - 线程之间共享的所有静态变量都必须通过锁或其他同步原语进行保护。提前做这种工作比以后修补问题要容易得多。

但是,在您的具体示例中,您将 UI 控件放在静态变量中 - 我绝对不建议这样做。 UI 控件位于 UI 线程上,并且在从不同线程调用时必须正确调用。抛开线程问题不谈,将控件放在静态变量中会带来麻烦 - 静态变量需要仔细登记才能清理 - 如果托管控件的表单消失,静态引用仍会将其保留在内存中(因为控件不能离开)。这可能会导致各种难以发现的问题。

如果您不熟悉 C# 中的 static,我建议您阅读 MSDN 了解更多详细信息。

【讨论】:

  • +1 - 我什至没有考虑到控件被植根。
  • 感谢您提供有关 UI 控件的提示,这些信息很有帮助。
  • @jramm 我很高兴它有用。要了解线程和 UI,请阅读 InvokeBeginInvoke。它的 TL;DR 是您必须在 UI 线程上调用控件 - 所有其他线程必须通过这些函数编组对 UI 线程的调用。
【解决方案2】:

我的静态类中的静态方法似乎有一个隐含的“this”变量

正确。无法实例化 static 类。因为没有实例变量,所以您可以使用类名本身访问static 类的成员。当您在 static 类的范围内时,访问其中的 static 成员不需要在其前面加上实例变量 (this)。

我希望你们中的一些人可能对这是否是个好主意有一些想法

真的.. 唯一的问题是在多线程环境中。由于此类及其数据将跨线程(单个实例..)共享,因此您需要围绕其访问进行同步。一般来说,static 类应该避免维护状态正是出于这个原因。

【讨论】:

  • 我想我明白你的意思,但谈论静态类的实例和引用可能有点令人困惑。
  • 我提到它是因为这是 OP 问题的一部分——因此是引号。如果这就是投反对票的原因,我很乐意重新措辞。
  • 我的主要问题是“一个静态类只有一个实例”;没有该类的实际实例。人们可能会对此感到困惑,然后想知道每个人都在谈论这个单例的东西。
  • 我不确定如何改写.. 我的编辑适合吗?
  • 没关系 - 我恢复了它。如果您可以提出不同的措辞,我会很乐意更新我的答案。
猜你喜欢
  • 2014-09-02
  • 2015-09-26
  • 1970-01-01
  • 2011-02-24
  • 2014-03-31
  • 1970-01-01
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多