This course takes code from the Data Types and Variables course and refines it using object-oriented (OO) principles. We explore some of the main concepts of OO programming during this process, such as encapsulation, code reuse, and inheritance.
Along the way, we learn more about essential code structures such as conditional evaluation with if-then-else statements, functions for grouping code that performs a specific task, and for-loops for dynamically repeating an action. We will also look at how .NET and C# have object-oriented baked-in as a fundamental design principle underpinning the framework and language.
Learning Objectives
- Understand the benefits of object orientation and what came before it
- Learn about essential code structures and turn code into a class
- Refine the class code and learn more object-oriented concepts
- Learn about inheritance, a fundamental object-oriented concept
- Understand how object-orientation is a foundation principle of C# and .NET
Intended Audience
This course is intended for those who already have an understanding of data types and variables in C# and now want to learn about object-oriented principles.
Prerequisites
To get the most out of this course, you should have an understanding of C# as well as basic data types: strings, numbers, and Booleans. In order to follow along with the demos, you should also have a working development environment, whether in Windows, Linux, or macOS.
Resources
The GitHub repository for this course can be found here.
If goto is not the way, then how. In the next step towards object orientation, I want to introduce the concepts for loops and functions. For loops are a much better way of repeating an action, and functions help us isolate functionality to perform a single task. Let's start by creating another application and pasting our evil goto code – oops, so much for not uttering that word again. In the program, which happens to be a class, there is already one function called main. A function is a segment or grouping of code enclosed in curly braces and has a name. A function can take in values as parameters and can return a value. When I say can return a value, it doesn't have to, but a return data type must be specified. If there is no return type, use the keyword void. Like the Main function, I'll define a PopulateRow function that returns nothing but takes as parameters an int array checks, an int variable called row, and a bool called sv – short for squareValue. Let's take the code that populates the checker array and paste it into PopulateRow. I'll change y to row and squareValue to sv. Next, I'll delete the y variable as we no longer need it and get rid of the horrible labels.
Now for the for loop. This for loop says, for this int variable i, initialize it with a starting value of zero, and while i is less than four, increment i by one. For every iteration of the loop, the code inside the loop's curly braces will be executed. You can see the for loop's definition inside the brackets is three statements, each separated by a semicolon like regular C# statements. The first is the definition of a loop counter or index variable. The index variable can be called anything and initialized to any value, but it must be a numerical data type. The following statement says while the loop index is less than a specified value, do the third statement, in this case, increment the index i by one.
I'll change PopulateRow to PopulateCheckerRow for a bit more clarity. Each time the for loop iterates, we call the PopulateCheckerRow, passing in the checkers int array, the for loop index, which specifies the row, and squareValue indicating the value of the row's first square. When we pass simple variables, like numbers and strings, as parameters, the variable's value is passed to the function, not the variable itself. This means whatever the function does to the variable only happens in the context of the function and leaves the variable unchanged in the code that called the function. It's no surprise that this is called passing by value. The ref keyword says pass a reference to this variable, meaning that function will be dealing with the same variable, even if it is known by another name within the function. In the Data types and Variables course, we looked at how a variable name referred to a memory location where a variable's value or data is stored. It is that memory location that is passed when passing a variable by reference. The irony is that C# passes array variables by reference as default behavior, so I needn't have used the ref keyword, but I wanted to make it explicit what is going on here. Because checkers and checks refer to the same data, PopulateCheckerRow isn't fully encapsulated as its code affects data external to it. As with the previous demo, we invert squareValue after each row has been populated. Let's run that. Excellent, still giving us the correct answer.
Using for loops and functions, we can refactor the code more. Within the PopulateCheckerRow function, we can use another for loop, similar to the one in Main. This time I'll call the for loop index variable col, so we have row and col and set sv to not sv through each loop iteration. Let's save and run - great.
While we're at it, we might as well refactor all those Console.WriteLine statements with a for loop, although it will be two for loops, one nested inside another. The first loop will be for the rows, so I'll call the index variable r, and the nested inner loop will be for the columns, so that will be c. This nested for loop structure says that we're going to loop four times for each column for each row. Instead of writing out a whole line as one string, we are writing one square at a time, and as such, we will use the write method of Console instead of WriteLine because we need all squares on the same line or row. We will still need to say when to print on a new row — placing a Console.WriteLine with an empty string after writing a row will achieve this. Let's save and run – great.
Printing is a distinct, self-contained process so that we can put it in its own function, which I'll call PrintCheckers, that takes the checkers array as its only parameter.
From a general programming point of view, for loops are an essential construct and probably the most efficient way to repeat the same action multiple times. In this demo, the number of times to execute the loop is hardcoded at four, but you could use a variable to make the loop dynamic.
Hallam is a software architect with over 20 years experience across a wide range of industries. He began his software career as a Delphi/Interbase disciple but changed his allegiance to Microsoft with its deep and broad ecosystem. While Hallam has designed and crafted custom software utilizing web, mobile and desktop technologies, good quality reliable data is the key to a successful solution. The challenge of quickly turning data into useful information for digestion by humans and machines has led Hallam to specialize in database design and process automation. Showing customers how leverage new technology to change and improve their business processes is one of the key drivers keeping Hallam coming back to the keyboard.