0

Four quick questions on static variables that the MSDN Faq and other basic guides seem to neglect.

  1. Is public static the same as static public?

    e.g.
    public static class Globals {...}

    vs.

    static public class Globals {...}

    Same? Different?

  2. It seems that -- like functions -- variables in a public static class in C# require public static status to be seen inside other classes via the static class's named global instance. Why is this? This seems non-intuitive from a naive perspective (it would seem public static class would provide a singular public instance of the class, with any public variables within available). Clearly this is not the case, so I wanted some perspective from C# experts as to why you have to make your member variables in your static class objects static to provide access.

    (Note: The MSDN Faq contains an example of a non-static class with static member vars, but nary a discussion on what if any differences having static members with a public static class has.) (i.e. What if any consequences are there of the doubly static status?)

    e.g.
    public static class Globals { public static Camera camera1; }//doubly static

  3. Is there ever a case where public non-static functions within a public static class are appropriate? I can see that you wouldn't want to expose some things, but wouldn't you just want to make them private in such a case. (The simpler the example, the better, I'm self-taught in C# and still trying to understand more complex topics like reflection, etc.)

  4. Curiously public enum inside a public static class are visible without a static keyword via the named global instance. Why is the typical static requirement not enforced here? Is there anything I should worry about if I use the visible public enum rather than a public static enum?

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

Thanks in advance. And apologies for the multiple questions, I was on the fence about whether to split this into multiple posts, but it's all related to C# static use, so I figured one post was most appropriate.

Community
  • 1
  • 1
Jason R. Mick
  • 5,177
  • 4
  • 40
  • 69

3 Answers3

2
  1. According to Method Specification:

A method-declaration may include a set of attributes (Section 17) and a valid combination of the four access modifiers (Section 10.2.3), the new (Section 10.2.2), static (Section 10.5.2), virtual (Section 10.5.3), override (Section 10.5.4), sealed (Section 10.5.5), abstract (Section 10.5.6), and extern (Section 10.5.7) modifiers.

Sequence doesn't matter

xandy
  • 27,357
  • 8
  • 59
  • 64
2
  1. Yes, the order doesn't really matter.
  2. Yes, a static class can only contain static members (with exception of #4), but they don't have to be public.
  3. Yes, you can have public static methods, but private static methods that your public static methods use
  4. Nested type declarations are not required to be static.

Another thing to remember is the "internal" visibility in c#. In my code bases I have found many uses for internal static classes (most of the time for extension methods).

Darren Kopp
  • 76,581
  • 9
  • 79
  • 93
  • Hi, great answers except for #3 you misunderstood me... I asked whether `public static class Example { public void MyFunc1() {...}` (a **NON-`static`**, NON-`private` member func. would ever be appropriate inside a `public static class`.... I realize the two questions sound similar, but the answers would be quite different, I'd assume! :) – Jason R. Mick Apr 30 '12 at 00:46
  • One more tiny clarification request... just to make sure I understand ... you can have `private ()` (non-`static` function) within a `public static class`, but you **can't** have `private ` member (non-`static`) within a `public static class` according to your answer for #2? – Jason R. Mick Apr 30 '12 at 00:49
  • 1
    `public static class Example { public void MyFunc1() {...}` is not valid C# code. The compiler will not let you put non-static members inside static classes. It also would not make sense because in order to call the non-static (also called "instance" members), you have to have an instance of the class created. However, you can not create an instance of a static class, so you could never call its non-static members. – CodingWithSpike Apr 30 '12 at 00:59
  • Oh okay, why not just make all `public` functions inside `public static class` declarations auto-`static` versus forcing the programmer to hand-define `static` in order to avoid syntax errors? – Jason R. Mick Apr 30 '12 at 01:02
  • 1
    The answer to this question also applies to the 2nd half of your comment above: http://stackoverflow.com/questions/3687201/accessing-non-static-enum-values-from-static-methods – CodingWithSpike Apr 30 '12 at 01:06
2

1: Order doesn't matter. There are standards of how to order things, for more readability, but as the compiler reads it all - it doesn't matter at all.

I personally thing that it would be best writing it as "public static", instead of "static public".

If you download ReSharper to your Visual Studio, it has predefined prioritizing to modifiers such as "static", "public", "readonly", etc... And will suggest you, when you are not following those standards, to correct the order of the modifiers. If you choose to work with a different prioritizing of the modifiers, you can change the ReSharper's settings to suit your preferred order.

Other than that - ReSharper does many other wonders and it highly recommended.


2: Static classes can only contain static members. "static" in the class means that the class can have no instances, and is declared as a being, sort of, as you said. "static" for members means a different thing: Normally, a member would be owned by the instance. Static members, however, are owned by the class - shared among all instances of the class and are used without an actual instance of the class.

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

Here, you can see that ZERO is static, which means it belongs to the class Math. So you could do:

Math.ZERO

Even if the Math class wasn't static, you would still access the ZERO member via the class itself. The ZERO will not be a member of a Math instance, because it belongs to the class, and not to an instance - hence "static member".


3: Number2 sort of answers this one as well. Non-Static class would mean that it can have instances of it and members that belong the instances, but you could also have class-members (static) that would belong to the class itself.

Example:

public class Quiz
{
    public static readonly int FAIL_GRADE = 45;

    public int Grade;
    public string StudentName;
}

So every Quiz has a grade and a student associated with it, but there is also a constant which belongs to the whole class "Quiz" which indicates what grade is considered as Fail Grade.

In the case above, you could also simply do:

public const int FAIL_GRADE = 45;

So you can learn that "const" means "static readonly", logically speaking. But in other cases, when you can't use "const" - you would have to use "static readonly". The "const" can only come before basic types, such as "int", "float", "bool", etc...

Here is an example where the "static" member is not readonly:

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
    }
}

In the above example, you can see that the static member of the class Student is used as a counter to how many times instances of Student performed a certain action (DoQuiz). The use of it here is actually not really good programming, since TestsTaken is really something that should be in Quiz, or in School class. But the example for "static" usage stands.


4: Enums in static classes don't require the "static" keyword, and in fact you can't declare a static Enum anywhere. Enum is not considered a member of a class, but a sub-type of it (could be sub-class, interface, enum, etc).

The fact that an Enum is declared within a class, simply means that if one wishes to use the Enum, he must reference the class as well. It would usually be places within a class for logic purposes, abstraction or encapsulation (would declare it "private" in this case - so it can be used within the class, but not outside of it).

Example:

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

In the above example, the SpecialSigns enum can be used from within the Math class, but is not visible to the outside.

You could also declare it public, so when one uses Math class, he could also use the SpecialSigns enum. In that case, you could also have SpecialSigns values as return types of methods, or types of public members. You can't do that when the SpecialSigns is private because the outside code does not have access to it - does not know of it's existence - and therefore cannot understand it as a return value, member type, etc.

Still, the SpecialSigns enum is not a member of the class, but only defined within the scope of it's recognition.

SimpleVar
  • 14,044
  • 4
  • 38
  • 60
  • 1
    Hi Yorye, I selected your answer as you answered all my questions and did so in the most illustrative way possible. I gave everyone else an upvote (and encourage anyone reading this to do so) given that they gave good insight, but you were the only one to properly understand and answer all my questions -- definitely learned a lot! – Jason R. Mick Apr 30 '12 at 01:15
  • P.S. I'll check out `ReSharper`. Working on kludging together a big `course-project` for my game class in `XNA` (sadly the class does not teach you `C#`, but hey it's grad school -- you are EXPECTED to learn on your own!). Going to do a cleanup of my code-base and launch a Windows Phone game in a month or two, so I'll be sure to pick up `ReSharper` in the process. – Jason R. Mick Apr 30 '12 at 01:23
  • ReSharper helps a lot with cleanup and refactoring. – SimpleVar Apr 30 '12 at 11:16