Answered Class protection levels

AlexJames

Well-known member
Joined
Mar 20, 2020
Messages
65
Programming Experience
10+
Hi All

I've been doing a fare amount of C# courses and one concept is causing me a bit of confusion. To follow best practices you must give your classes the lowest protection/access level possible, the class should know as little as possible about the rest of the application. What i'm struggling to understand is, the majority of the work is done in the classes and the only way to access the class from say a users form is to have for example a users class that is set to public, you need public properties as well as public methods in order to access what you need to from your form. How do you maintain strict access/protection levels for your classes if everything has to be public in order for you to access them ?

Many Thanks
AJ.
 
class should know as little as possible about the rest
Access levels is about protecting types and members from outside use. What you described there sounds more like avoiding dependencies.
There are four basic access modifiers: public, private, protected, internal and a couple of combinations.

I'll show an example using the first three with common elements, a class with a field, a property, an event and a method for raising the event:
C#:
public class Example
{
    private int myVar;

    public int MyProperty
    {
        get { return myVar; }
        set
        {
            if (myVar != value)
            {
                myVar = value;
                OnMyPropertyChanged(EventArgs.Empty);
            }
        }
    }

    public event EventHandler MyPropertyChanged;

    protected virtual void OnMyPropertyChanged(EventArgs e)
    {
        MyPropertyChanged?.Invoke(this, e);
    }
}
The class Example is public and can be accessed by anyone.
  • The field myVar keeps the state of the object, only the class itself should be able to modify it directly so it is private.
  • The property MyProperty is public, it provides external access to the object state. This also allowes perform code when state is returned or set (although it may not need to, see auto properties).
  • The event is public and can be used by consumers of the class.
  • By common code conventions the event is coupled with a protected OnEvent method that raises the event, this allows classes inheriting this class to override the method and add behaviour to the class before and after the event is raised.
The fourth access modifier internal is commonly used when writing class libraries, to allow different classes/members within the library to interact, while protecting them from external consumers.
 
What i'm struggling to understand is, the majority of the work is done in the classes and the only way to access the class from say a users form is to have for example a users class that is set to public, you need public properties as well as public methods in order to access what you need to from your form. How do you maintain strict access/protection levels for your classes if everything has to be public in order for you to access them ?
Welcome to the world of class or API design. Forgive if the following is fluffy and involves a lot of hand waving. Computer science is still an art, not a science.

In general, the answer to your question would sound very koan like: "Expose enough to get the job done.".

That may not sound very helpful, but you also need to remember two other things: object oriented programming is mostly about message passing; and some objects/types only role is to hold data.

Let's tackle the second one first: some objects only role to hold data. If you have heard or seen the acronym POCO (or POJO), you know that these stand for Plain Old C# Object (or Plain Old Java Object). These are C# classes where the majority of the members are public properties. Some of them may have factory methods, and/or helper methods, but in general you would use these like a data record read from/to a database.

If there are objects that just hold data, then there are objects that do work. The way you tell these objects to do work is to pass them messages and tell them to do something. "Passing messages" is just a fancy way of saying call methods in the C# world, but other languages have other ways of telling an object to do so some kind of work. Yes, these objects may also have public properties exposed which modify how the object performs the job, but in general the idea is these properties control what is done, and not necessarily, how it it is done.

It takes a while get the art of API design just right. The goal is loose coupling, tight cohesion. Learning to do this in an object oriented way takes a while if you are coming from a procedural programming background.

This maybe a good read to influence how to think of what needs to be exposed:
 
Hi Guys

Thank you so much for your excellent explanations, this information is invaluable. it's going to take me a while to get the hang of it but i'll go through my code tomorrow and see where i can improve based on what you guys have mentioned. I'll post back with any follow up questions.

Many thanks again
AJ
 
Back
Top Bottom