1
public class Person
{
    private string _name; // always recommended to be private

    private static string s_homePlanet; // recommended?
}

As mentioned in the question the practice of encapsulation recommends that I always declare my instance fields as private. To keep an instance's information as hidden.

According to Fields (C# Programming Guide)

"Generally, you should use fields only for variables that have private or protected accessibility."

According to C# Field Design

"The principle of encapsulation is one of the most important notions in object-oriented design. This principle states that data stored inside an object should be accessible only to that object. This interpretation immediately implies that all fields must be private."

I know a static field stores information that is shared amongst instances of a type; thus, the informaton stored within a static field is not specific to any instance. With that being said is it reccomded that I always declare a static field as private???

MVPyro
  • 43
  • 5

2 Answers2

2

Yes, with the same logic: a static field should only be accessible from that class, and its content should only ever be exposed via getters and setters. This has several benefits:

  • The class code can enforce the consistency of its internal state. If you have a public field, then any other class can mess with its content, with no guarantees that the assumptions of the class will still hold. (e.g. if a Window class holds instances static field that lists all the creaated windows, if it is public, foreign code could empty that list)

  • If sometime in the future you decide you would like to have side-effects to setting or reading a field (e.g. log whenever it changes), it is easy to do if you use a setter and getter functions; but if you allow public access to a field, you would have to refactor your code into using getters and setters.

  • If you decide to change the internal workings of your class, even restructure your fields, as long as all the methods have the same signature you can do this easily if the only access to them is via the defined methods. However, if you expose the data, then it is not possible to restructure it if you wish to remain backward-compatible.

None of these reasons change if the field is a class field or an instance field.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • You made a great point in the second bullet point. Thanks. Though have there been any cases where you personally saw it neccessary to declare a static field as non-private (as public or interal)? – MVPyro Mar 15 '23 at 07:20
  • You can be lazy and have public fields if you don't think you will need to maintain the code for long (one-shots and such). However, I remember once I got tasked to do a quick tool for a week, and then was told to continue to develop the same thing for the next year and a half, so it is dangerous to assume the lazy approach will be fine. `internal` justification is the same as `private`, but on a level of a whole file, where you might have several classes working together, presenting a unified API outside the file but all the classes inside being "friends". – Amadan Mar 15 '23 at 07:25
  • That said, some languages (notably, Ruby) don't have even an option of public fields (except if you hack using introspective methods), and have extremely succint ways to define default setters and getters, enforcing this suggestion into a law. – Amadan Mar 15 '23 at 07:27
  • I guess it's better to be safe than sorry. I'll stick to declaring my static fields as private. Your answer was very helpful. And thanks for the anecdote. If you ever feel like adding on to your answer/comments with more helpful information that might aid me or others please feel free to do so. Thanks. – MVPyro Mar 15 '23 at 07:31
1

I would argue that in the vast majority of cases, static fields should be read only, and represent some type of immutable state. Shared global state between instances should in general be avoided.

For such global immutable fields the importance of keeping fields private is greatly reduced. You do not have to worry about internal state or side effects. So as long as it is immutable, I would not mind it being public.

If you actually need shared state there are often other alternatives, for example using a dependency injection container and injecting a shared dependency into all instances.

If you absolutely need a mutable static field, then you should absolutely make it private. This is even more important than for non-static fields, since the scope for a public static fields are the entire program, and that can easily get messy.

JonasH
  • 28,608
  • 2
  • 10
  • 23