Lesson 42 - Accessibility Modifiers, Fields and Properties

Tutorial Series: Free C# Fundamentals via ASP.NET Web Apps

Previous Article  |  Next Article

Get GitHub Code

This lesson will cover the topic of accessibility modifiers as well as private fields and public properties. Access modifiers are prefixed to classes, class-level variables, and methods, in order to determine the “visibility” of these elements throughout your codebase. There are five different access modifiers, however, you will mainly be concerned with just the public and private modifiers:


You can learn more about access modifiers by going to the official MSDN article describing them:



Don’t get confused by the word “struct.” A struct is a special kind of class that looks just like an ordinary class, but with a technical twist. You won’t have to worry about structs very much, in this series of lessons, so wherever you see it referenced, you can take it to generally mean a class.

Step 1: Create a New Project

To illustrate the difference between these different modifiers, let’s go back to where we left off in the previous lesson and save it to a new project called “CS-ASP_042.” You will recall that we made the Character and Dice classes, both from an outside assembly namespace, prefixed as public:


Step 2: Default Protection Levels

If you were to remove these modifiers, the classes would default to the internal protection level. This means that it’s visible by other classes within the same namespace/assembly (as in “internal to this assembly”):


However, since the CS_ASP_042 assembly is an external assembly, the Default class can no longer “see” these outside classes:


Step 3: Understanding Public vs Private Protection Levels

By setting a class – or a class member – to “public” you are allowing it to be visible across all classes and assemblies in your project. It is the most open access modifier possible. By contrast, private is the most closed modifier possible, which means that whatever is prefixed as private is visible only within its containing class/context:


Here, num1 is private and therefore only visible to another member within the same class that wants to reference it:


However, since it is private to the context in which it was declared it won’t be visible outside of this context (in another class, for example):


As you see, in this example, Intellisense doesn’t even show the element that is private to the SomeClass context. That alone is a common reason to keep elements private. Otherwise, if everything was public, a codebase would quickly be overwhelmed with unnecessary options that have no practical use and would only serve the potential for confusion and errors. Furthermore by keeping internal implementation private where possible, you reduce inter-dependencies in a codebase. This de-coupling of code dependencies further reduces complexity and errors. With that in mind, access modifiers are a powerful way of enforcing a key Object-Oriented-Programming tenet called “encapsulation” that encompasses the concept of abstraction and hiding implementation details.


While outside the scope of this lesson, the concept of coupling in Object-Oriented Programming is an important one. The basic idea is that, whenever a class “knows” a lot about another class, and depends on it to perform some of its own functions, the classes become inextricably linked or coupled together. So, when one class has to change - in order to deal with some update, for example – the other class may also change. The problem becomes especially difficult to manage when a variety of other classes also have some sort of dependency on the state of the changed classes. This can lead to a highly unmaintainable codebase. You can imagine how deep of a problem this represents in software development where it’s common for developers to throw out unmaintainable code and simply start from scratch.

Step 4: A List of Access Modifiers

Here is a list of the default access modifiers for the most common code elements (“default” here means whenever the access modifier is omitted):



There is one other modifier that we haven’t gone over yet and that is “protected.” This modifier sits somewhere between public and private. It grants visibility, across all assemblies (unless the “internal” modifier is added), to any class which shares an inheritance hierarchy. Inheritance is a topic that we will be looking at later, however, just keep this in mind for now.

Step 5: Understanding Fields vs Properties

Up to this point we have been talking about class members as, either, variables called “properties” or executable code blocks called “methods”. However, there is another type of common class member, and that is a field. Fields are closer to what you’ve come to think of as variables than properties. Properties and fields both hold values, or object references, that can be read from, or written to. However, properties have their own code block (squiggly brackets) that can handle specific implementation details, somewhat similar to a method. We have only seen the simplest version of this in what is called auto-implemented properties, where the get and set code is simplified, and hidden away. Here, the Sides class-level variable is an auto-implemented property and below it is the random class level variable that is an ordinary field:


Here the field is prefixed as private because we have no intention of letting outside classes access it directly. However, the Roll() method can still access it because, both, the field and the method belong to the same class. The Roll() method, meanwhile, is publicly visible to all classes. The result of this is that outside access to the random field is indirect; it is hidden behind the implementation details of the Roll() method. This kind of implementation – a private field “hidden” behind a public method that implements it – is very similar to how properties work. An auto-implemented property is just a shorthand for having a private field hidden behind the implementation of a public property. Here is what is actually going on behind the simple Sides get and set:

  1. A private field is created.

  2. A public property is created.

  3. The property can read (get) whatever value is held in the backing field.

  4. The property can write (set) to the backing field whatever value is being assigned to it elsewhere in code (“implied by value”).



To get the code-snippet shortcut for a full property (along with its backing field) type "propfull" and then hit the tab key twice.

Here in the Character class we’re attempting to set the Sides property (which actually sets the value to the private sides field) and that works fine because, currently, the property’s set is public:


Step 6: Access Modifiers on Property ‘get’ and ‘set’

However, you can modify the property so that it can be read from (get) publicly, but written to (set) privately:


This renders it impossible to set this value in the Character class. However, since the get is still public you can still retrieve the value publicly:


Step 7: Why Use ‘private set’

Perhaps this private set implementation is used because we are afraid of someone – another programmer using our codebase, for example – giving a value for this property that is not valid, and we want to keep this validation check as a helper method within the Dice class. However, because a property is really just a “gate keeper” for the backing field and has its own code block it can execute whenever a get/set is attempted, and we can put this validation check directly into the property itself. Here, if we try to set the property with anything greater than six – which in return actually sets the private field – a runtime error occurs (you can add specific exception handling):


Related Articles in this Tutorial:

Lesson 1 - Series Introduction

Lesson 2 - Installing Visual Studio 2015

Lesson 3 - Building Your First Web App

Lesson 4 - Understanding What You Just Did

Lesson 5 - Working with Projects in Visual Studio

Lesson 6 - Simple Web Page Formatting in Visual Studio

Challenge 1

Solution 1

Lesson 7 - Variables and Data Types

Lesson 8 - Data Type Conversion

Lesson 9 - Arithmetic Operators

Lesson 10 - C# Syntax Basics

Challenge 2 - ChallengeSimpleCalculator

Solution - ChallengeSimpleCalculator

Lesson 11 - Conditional If Statements

Lesson 12 - The Conditional Ternary Operator

Challenge 3 - ChallengeConditionalRadioButton

Solution - Challenge Conditional RadioButton

Lesson 13 - Comparison and Logical Operators

Lesson 13 Challenge - First Papa Bob's Website

Solution - Challenge First Papa Bob's Website

Lesson 14 - Working with Dates and Times

Lesson 15 - Working With Spans of Time

Lesson 16 - Working with the Calendar Server Control

Challenge 4 - Challenge Days Between Dates

Solution - Challenge Days Between Dates

Lesson 17 - Page_Load and Page.IsPostBack

Lesson 18 - Setting a Break Point and Debugging

Lesson 19 - Formatting Strings

Challenge 5 - Challenge Epic Spies Assignment

Solution - Challenge Epic Spies Assignment

Lesson 20 - Maintaining State with ViewState

Lesson 21 - Storing Values in Arrays

Lesson 22 - Understanding Multidimensional Arrays

Lesson 23 - Changing the Length of an Array

Challenge 6 - Challenge Epic Spies Asset Tracker

Solution - Challenge Epic Spies Asset Tracker

Lesson 24 - Understanding Variable Scope

Lesson 25 - Code Blocks and Nested If Statements

Lesson 26 - Looping with the For Iteration Statement

Challenge 7 - Challenge For Xmen Battle Count

Solution - Challenge For Xmen Battle Count

Lesson 27 - Looping with the while() & do...while() Iteration Statements

Lesson 28 - Creating and Calling Simple Helper Methods

Lesson 29 - Creating Methods with Input Parameters

Lesson 30 - Returning Values from Methods

Lesson 31 - Creating Overloaded Methods

Lesson 32 - Creating Optional Parameters

Lesson 33 - Creating Names Parameters

Lesson 34 - Creating Methods with Output Parameters

Challenge 8 - Challenge Postal Calculator Helper Methods

Solution - Challenge Postal Calculator Helper Methods

Mega Challenge Casino

Solution - Mega Challenge Casino

Lesson 35 - Manipulating Strings

Challenge 9 - Phun With Strings

Solution - Challenge Phun With Strings

Lesson 36 - Introduction to Classes and Objects

Challenge - Hero Monster Classes Part 1

Solution - Hero Monster Classes Part 1

Challenge - Hero Monster Classes Part 2

Solution - Challenge Hero Monster Classes Part 2

Lesson 37 - Creating Class Files Creating Cohesive Classes and Code Navigation

Lesson 38 - Understanding Object References and Object Lifetime

Lesson 39 - Understanding the .NET Framework and Compilation

Lesson 40 - Namespaces and Using Directives

Lesson 41 - Creating Class Libraries and Adding References to Assemblies

Lesson 42 - Accessibility Modifiers, Fields and Properties

Lesson 43 - Creating Constructor Methods

Lesson 44 - Naming Conventions for Identifiers

Lesson 45 - Static vs Instance Members

Challenge 10 - Challenge Simple Darts

Solution - Challenge Simple Darts

Lesson 46 - Working with the List Collection

Lesson 47 - Object Initializers

Lesson 48 - Collection Initializers

Lesson 49 - Working with the Dictionary Collection

Lesson 50 - Looping with the foreach Iteration Statement

Lesson 51 - Implicitly-Typed Variables with the var Keyword

Challenge 11 - Challenge Student Courses

Solution - Challenge Student Courses

Mega Challenge War

Solution - Mega Challenge War

Lesson 52 - Creating GUIDs

Lesson 53 - Working with Enumerations

Lesson 54 - Understanding the switch() Statement

Lesson 55 - First Pass at the Separation of Concerns Principle

Lesson 56 - Understanding Exception Handling

Lesson 57 - Understanding Global Exception Handling

Lesson 58 - Understanding Custom Exceptions

Lesson 59 - Creating a Database in Visual Studio

Lesson 60 - Creating an Entity Data Model

Lesson 61 - Displaying the DbSet Result in an ASP.NET GridView

Lesson 62 - Implementing a Button Command in a GridView

Lesson 63 - Using a Tools-Centric Approach to Building a Database Application

Lesson 64 - Using a Maintenance-Driven Approach to Building a Database Application

Lesson 65 - Creating a New Instance of an Entity and Persisting it to the Database

Lesson 66 - Package Management with NuGet

Lesson 67 - NuGet No-Commit Workflow

Lesson 68 - Introduction the Twitter Bootstrap CSS Framework

Lesson 69 - Mapping Enum Types to Entity Properties in the Framework Designer

Lesson 70 - Deploying the App to Microsoft Azure Web Services Web Apps

Papa Bob's Mega Challenge

Papa Bob's Mega Solution Part 1 - Setting up the Solution

Papa Bob's Mega Solution Part 2 - Adding an Order to the Database

Papa Bob's Mega Solution Part 3 - Passing an Order from the Presentation Layer

Papa Bob's Mega Solution Part 4 - Creating the Order Form

Papa Bob's Mega Solution Part 5 - Adding Enums

Papa Bob's Mega Solution Part 6 - Creating an Order with Validation

Papa Bob's Mega Solution Part 7 - Calculating the Order Price

Papa Bob's Mega Solution Part 8 - Displaying the Price to the User

Papa Bob's Mega Solution Part 9 - Creating the Order Management Page


Please login or register to add a comment