【问题标题】:C# Static Order, Member Variables, Member EnumsC# 静态顺序、成员变量、成员枚举
【发布时间】:2026-02-15 10:55:01
【问题描述】:

MSDN Faqother basic guides 似乎忽略的关于静态变量的四个快速问题。

  1. public static 是否与static public 相同?

    例如
    public static class Globals {...}

    vs.

    static public class Globals {...}

    一样吗?不一样?

  2. 似乎——就像函数一样——C# 中的public static class 中的变量需要通过static 类的命名全局实例在其他类中看到public static 状态。为什么是这样?从幼稚的角度来看,这似乎是不直观的(似乎public static class 将提供class 的单个public 实例,其中包含可用的任何公共变量)。显然情况并非如此,所以我想从C# 专家那里获得一些观点,了解为什么必须在static class 对象static 中创建成员变量以提供访问权限。

    (注意:MSDN Faq 包含一个非static classstatic 成员变量的示例,但没有讨论如果有任何差异具有public static classstatic 成员。)(即,如果双重static 状态有什么后果?)

    例如
    public static class Globals { public static Camera camera1; }//doubly static

  3. public static class 中的public non-static 函数是否合适?我可以看到你不想暴露一些东西,但在这种情况下你不想让它们private。 (例子越简单越好,我是在C#自学的,还在努力理解更复杂的话题,比如reflection等)

  4. 奇怪的是,public static class 中的 public enum 在没有 static 关键字的情况下通过命名的全局实例可见。为什么这里没有强制执行典型的static 要求?如果我使用可见的public enum 而不是public static enum,有什么需要担心的吗?

    public static class Globals { public enum Dummy { Everything=42}; }
    //Enum is visible w/out static!

提前致谢。对于多个问题,我很抱歉,我在考虑是否将其拆分为多个帖子,但这都与C# static 的使用有关,所以我认为一个帖子是最合适的。

【问题讨论】:

    标签: c# class static enums visibility


    【解决方案1】:

    1:顺序无关紧要。有一些关于如何排序的标准,以提高可读性,但是当编译器读取所有内容时 - 这根本不重要。

    我个人认为最好将其写为“public static”,而不是“static public”。

    如果您将 ReSharper 下载到您的 Visual Studio,它已预定义了“静态”、“公共”、“只读”等修饰符的优先级...并且会建议您,当您不遵循这些标准时,更正修饰符的顺序。如果您选择使用不同优先级的修饰符,您可以更改 ReSharper 的设置以适合您的首选顺序。

    除此之外 - ReSharper 还创造了许多其他奇迹,强烈推荐。


    2:静态类只能包含静态成员。类中的“静态”意味着该类可以没有实例,并且如您所说,被声明为某种存在。成员的“静态”意味着不同的东西:通常,成员将由实例拥有。然而,静态成员归类所有 - 在类的所有实例之间共享,并且在没有类的实际实例的情况下使用。

    public static class Math
    {
        public static readonly int ZERO = 0;
    }
    

    在这里,您可以看到 ZERO 是静态的,这意味着它属于 Math 类。 所以你可以这样做:

    Math.ZERO
    

    即使 Math 类不是静态的,您仍然可以通过该类本身访问 ZERO 成员。 ZERO 不会是 Math 实例的成员,因为它属于类,而不属于实例 - 因此是“静态成员”。


    3: Number2 也回答了这个问题。非静态类意味着它可以拥有它的实例和属于这些实例的成员,但您也可以拥有属于该类本身的类成员(静态)。

    例子:

    public class Quiz
    {
        public static readonly int FAIL_GRADE = 45;
    
        public int Grade;
        public string StudentName;
    }
    

    所以每个测验都有一个成绩和一个与之关联的学生,但还有一个属于整个班级“测验”的常数,它表示什么成绩被认为是不及格。

    在上述情况下,您也可以这样做:

    public const int FAIL_GRADE = 45;
    

    因此,从逻辑上讲,您可以了解到“const”的意思是“静态只读”。 但在其他情况下,当您不能使用“const”时 - 您将不得不使用“static readonly”。 “const”只能出现在基本类型之前,例如“int”、“float”、“bool”等...

    这是一个“静态”成员不是只读的示例:

    public static class Student
    {
        public static int TestsTaken = 0;
    
        public string Name;
    
        public int DoQuiz(Quiz quiz, Answers answers)
        {
            TestsTaken++;
    
            // Some answers checking logic and grade returning
        }
    }
    

    在上面的例子中,你可以看到Student类的静态成员被用来作为Student实例执行某个动作(DoQuiz)的次数的计数器。在这里使用它实际上并不是很好的编程,因为 TestsTaken 确实应该在 Quiz 或 School 课堂中使用。但是“静态”用法的示例仍然存在。


    4:静态类中的枚举不需要“static”关键字,事实上你不能在任何地方声明静态枚举。枚举不被视为类的成员,而是它的子类型(可以是子类、接口、枚举等)。

    在一个类中声明一个 Enum 的事实,仅仅意味着如果一个人想要使用 Enum,他也必须引用这个类。出于逻辑目的、抽象或封装的目的,它通常位于类中(在这种情况下将其声明为“私有” - 因此它可以在类内使用,但不能在类外使用)。

    例子:

    public static class Math
    {
        private enum SpecialSigns
        {
            Sigma,
            Alpha,
            Pi,
            etc
        }
    }
    

    在上面的示例中,SpecialSigns 枚举可以在 Math 类中使用,但对外不可见。

    您也可以将其声明为 public,因此当使用 Math 类时,他也可以使用 SpecialSigns 枚举。在这种情况下,您还可以将 SpecialSigns 值作为方法的返回类型或公共成员的类型。当 SpecialSigns 是私有的时,您不能这样做,因为外部代码无法访问它 - 不知道它的存在 - 因此无法将其理解为返回值、成员类型等。

    不过,SpecialSigns 枚举不是该类的成员,而是仅在其识别范围内定义。

    【讨论】:

    • 嗨,Yorye,我选择了你的答案,因为你回答了我所有的问题,并且尽可能以最具说明性的方式这样做。鉴于其他人给出了很好的见解,我给了其他人一个赞成票(并鼓励任何阅读这篇文章的人这样做),但你是唯一一个正确理解和回答我所有问题的人——肯定学到了很多!
    • P.S.我会检查ReSharper。努力为我在XNA 的游戏课拼凑一个大的course-project(遗憾的是,这个课并没有教你C#,但是嘿,这是研究生院——你应该自学!)。打算在一两个月内清理我的代码库并推出一款 Windows Phone 游戏,所以我一定会在此过程中接听ReSharper
    • ReSharper 在清理和重构方面有很大帮助。
    【解决方案2】:
    1. 根据Method Specification

    方法声明可能包括一组属性(第 17 节)和四个访问修饰符(第 10.2.3 节)、新的(第 10.2.2 节)、静态(第 10.5.2 节)、 virtual(第 10.5.3 节)、override(第 10.5.4 节)、sealed(第 10.5.5 节)、abstract(第 10.5.6 节)和 extern(第 10.5.7 节)修饰符。

    顺序无关紧要

    【讨论】:

      【解决方案3】:
      1. 是的,顺序并不重要。
      2. 是的,静态类只能包含静态成员(#4 除外),但它们不必是公共的。
      3. 是的,您可以拥有公共静态方法,但您的公共静态方法使用私有静态方法
      4. 嵌套类型声明不需要是静态的。

      要记住的另一件事是 c# 中的“内部”可见性。在我的代码库中,我发现了内部静态类的许多用途(大部分时间用于扩展方法)。

      【讨论】:

      • 嗨,除了#3,你误解了我的意思,很好的答案...我问public static class Example { public void MyFunc1() {...} (a NON-static, NON-private member func . 在public static class.. 中是合适的。我意识到这两个问题听起来很相似,但我想答案会完全不同!:)
      • 一个更小的澄清请求......只是为了确保我理解......你可以在public static class中拥有private <return-type> <func-name>(<args>)(非static函数),但是你根据您对#2 的回答,在public static class 中不能拥有private <type> <name> 成员(非static)?
      • public static class Example { public void MyFunc1() {...} 不是有效的 C# 代码。编译器不允许您将非静态成员放入静态类中。这也没有意义,因为为了调用非静态(也称为“实例”成员),您必须创建类的实例。但是,您不能创建静态类的实例,因此您永远不能调用它的非静态成员。
      • 哦,好吧,为什么不让所有public 函数在public static class 中声明为auto-static,而不是强迫程序员手动定义static 以避免语法错误?跨度>
      • 这个问题的答案也适用于你上面评论的第二部分:*.com/questions/3687201/…
      最近更新 更多