Stack Overflow GitHub RSS Feed

Byte-sized C# Programming: Classes

Published: January 13, 2019

As stated in the end of the previous post, we are eager to get programming. There are two more main concepts that need to be discussed before we can create our first program. The main focus of this article will be classes. The end of the article will briefly discuss namespaces and point out a few resources to show how to get started writing your first program.

An easy way to start thinking about classes would be to envision them as digital representations of real world objects. Every time we create a new ‘instance’ of the class, it will contain all the pieces we have defined in our class. To continue with the example we’ve been using thus far in the series…

Let’s assume the CEO is so pleased with the progress of this rewards program that he wanted to print off membership cards for all of his staff members. To help facilitate the further automation of this system, we are going to want the program to be able to store information about this card and utilize this information in the program.

When creating a class, a good place to start, is to think of the characteristics that the item to be represented possess. There are many characteristics that could come to mind like card size, the material the card is made of, color of the card, etc. When creating a class though, one should try to think of the characteristics of the card that will make a difference to the program. When creating a user interface, the above characteristics might define how we represent the card on the screen. When starting with programming, the user interface adds a whole level of complexity that could easily detract from the core concepts that we are trying to focus on.

For the moment then, let’s think of other characteristics of the card that would be more meaningful for the program we are creating. The card really represents a member of the program. So far, we want to track a few data points for each program member. The rewards program we’ve discussed needs to know the number of miles the member has traveled this year and the number of months they’ve been employed in this organization. As a person travels, we know that they will need to add miles to their account and at the end of the year, we know we will want to get a monthly average of their miles traveled.

Thanks for the overview, but I already know what a rewards program is. What is this ‘class’ business and how do they synthesize?

Patience young grasshopper. “Be not afraid of growing slowly, be afraid only of standing still.”

All joking aside, I’ve found that those who are better at thinking about the things they want to represent in an abstract manner, as we did above, have a much easier time creating code and communicating intent through their code. Variables are a necessary part of any program. Understanding what a method is and what it does is also critical for being able to write code(if for no other reason than you want to be able to rely on the genius of others and not write every piece of functionality yourself).

To create an executable(a runnable program) you technically need one class and one namespace. If one wanted to, they could always use the default for both of these, cram all of their code into the defaults and not have to understand them that well. Classes and namespaces are a very powerful tool for communication in code though and practically speaking are the only real way programs are written. That being the case, it makes sense to discuss the thought process behind the creation of these items to shape the discussion.

Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, drool drool, Bueller Bueller

Ok, wake up, wake up. Let’s dive in. Here is how our first class will start off looking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class RewardsMember
{
  string Id { get; set; }
  string Name { get; set; }
  int MilesTraveledYearToDate { get; set; }
  int MonthsWorkedYearToDate { get; set; }

  RewardsMember()
  {
    Id = Guid.NewGuid().ToString();
  }

  void UpdateMilesTraveled(int milesToAdd)
  {
    MilesTraveledYearToDate = MilesTraveledYearToDate + milesToAdd;
  }

  decimal GetEmployeesMonthlyAverage()
  {
    return MilesTraveledYearToDate / MonthsWorkedYearToDate;
  }
}

Woah, overload…

Yes, it can look a bit overwhelming at first glance, but I think if you don’t get lost in the code and read the words that are there, you will start to see the items we outlined above.

Let’s break it down step by step(or byte by byte ;) ).

To start off, there is the keyword class. This tells the compiler that what comes next is the characteristics that the item to be represented by this class possess. This is followed by the name we chose for our class RewardsMember because we want each instance of our class to represent one member in the rewards program. The first and last {} provide the syntactical bookends for the block of code that encases the characteristics for our rewards member class.

Within those curly braces are three distinct areas.

The first four lines contain the class’ properties.

1
2
3
4
string Id { get; }
string Name { get; }
int MilesTraveledYearToDate { get; }
int MonthsWorkedYearToDate { get; }

The easiest way to look at a property is a class instance’s variable. This isn’t 100% accurate as there is more you can do with them than variables, but let’s start by envisioning them as variables. So what exactly does this mean? Every new RewardsMember we create will have 4 variables inside of it. One representing the unique identifier assigned to this member(Id) which is of type string. One representing the reward member’s name, also of type string. The last two are of type int and will represent the reward member’s year-to-date miles traveled and months worked respectively.

The next four lines are called an instance constructor.

1
2
3
4
RewardsMember()
{
  Id = Guid.NewGuid().ToString();
}

When creating a new RewardsMember in our program, this is the method that will be called. If there is anything that needs to happen to setup any of the properties in the class with initial values, those steps should be placed here. Here(with a little bit of hand-waving), I’m creating a unique value to assign to the rewards member when they are created. This would be likened to the random group of numbers that appear on a credit card. It is meaningless to the holder, but that is how the cardholder and their transactions are identified in the billing system. Here, that is how our reward’s member can be identified in our system. One quick note, while I’ve referred to it as a method, you will notice two distinct qualities about it. It has the same name as the class and it doesn’t define a return value(actually the return value is of type RewardsMember). While we won’t go into more detail now, know that these properties hold true of all ‘instance constructors’.

Finally we gave the class two methods.

1
2
3
4
5
6
7
8
9
void UpdateMilesTraveled(int milesToAdd)
{
  MilesTraveledYearToDate = MilesTraveledYearToDate + milesToAdd;
}

decimal GetEmployeesMonthlyAverage()
{
  return MilesTraveledYearToDate / MonthsWorkedYearToDate;
}

With this, every instance of the RewardsMember class will have the ability to update its variable that stores how many miles the member has traveled this year and another that will be able to return to the program the monthly average miles traveled for the rewards member.

Double Woah. What you just wrote feels like it should make sense, but also feels full of jargon. One thing you repeated a bunch was an ‘instance’ of a class. What does this mean and how do we create one?

Both are excellent questions and I think walking through the answers to them will help elucidate the rest of the above jargon. One further point about classes. In addition to all of the above, by creating a class definition, we are also creating a new type in C#.

Huh?

Ok, let’s start looking at how to use this class now. To utilize this class after it has been defined as above would be to create a new ‘instance’ of this class. Here is how we would do that.

1
RewardsMember johnDoe = new RewardsMember();

We declare a variable of type RewardsMember, call it johnDoe, create a new instance of our RewardsMember class and assign it to that variable.

Great…I think. We now have an ‘instance’ of our class, but what can we do with it?

Well, as was stated before, with each ‘instance’ of our class we get the ‘variables’ we defined in it and their methods. So now if we wanted to access the Id for John Doe, we would do that as follows: string johnDoesId = johnDoe.Id;. If we wanted to record the miles traveled on a trip for John Doe, that would be done as follows: johnDoe.UpdateMilesTraveled(859);.

If we wanted to create a reward member for Jane Doe? Yup, you guessed it, we would do RewardsMember janeDoe = new RewardsMember();. If we wanted to see how many miles she’s traveled thus far, we would do int janeDoesYearToDateMilesTraveled = janeDoe.MilesTraveledYearToDate;.

What value do you think janeDoesYearToDateMilesTraveled would hold now? If you guessed 859, you wouldn’t be correct, but is a common source of confusion when getting started. Since the RewardsMember class is a set of characteristics and each ‘instance’ of that class has its own set of ‘variables’ and methods, janeDoesYearToDateMilesTraveled would hold the value 0 currently. It wouldn’t hold 859 as that value was stored in johnDoe’s MilesTraveledYearToDate ‘variable’. The 0 value is the default value for an int, not a topic for this post, but just an FYI as to where that value came from.

Great!

I think I’m starting to grasp classes, you mentioned that you would talk about ‘namespaces’ as well though. What are they and why do I need to care?

Yeah, you’re right. I think this is a good start for understanding classes. There is so much more to talk about, but it will have to wait for later as this post is getting a bit long. On to namespaces.

I mentioned before that, “To create an executable(a runnable program) you technically need one class and one namespace. If one wanted to, they could always use the default for both of these…”. Let’s take a look at what that looks like now, give a brief explanation, point out some tools to utilize to get started and send you on your way until next time.

If you were to create a new ‘Console App’ project with one of the tools that will be discussed soon, you will get a few files, but the main one will look as follows.

1
2
3
4
5
6
7
8
9
10
11
12
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

There are a few things in here that we haven’t discussed yet. For the sake of brevity, I’m going to skip them and come back to them another time. Most of it should look familiar though. We have a Program class and a method called Main. In C# land, when any program is started, the method named Main will be the first method invoked, kicking off the program. Now, methods and classes are familiar, but what is the first line namespace ConsoleApp1? It might be a little hard to imagine now, but as your code grows in size and complexity, it is very possible you will want to create two classes with the same name or a class with a name that is used in a common external library. A namespace creates a segregation of code that can allow this.

I know this is a little abstract, I’ll try to explain a little more and then it will just have to be taken on faith until we go further down the coding rabbit hole. Let’s say we created our RewardsMember class in the ConsoleApp1 namespace as follows:

1
2
3
4
5
6
7
namespace ConsoleApp1
{
  class RewardsMember
  {
    ...
  }
}

If we wanted to create our two members in the program above instead of the Console.WriteLine bit, we could do:

1
2
3
4
5
6
7
8
9
10
11
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            RewardsMember johnDoe = new ConsoleApp1.RewardsMember();
            RewardsMember janeDoe = new RewardsMember();
        }
    }
}

ConsoleApp1.RewardsMember() is the ‘fully qualified way of referring to our class. In this scenario, RewardsMember() would be the more common way to utilize the class though. Since both Program and RewardsMember classes are in the same namespace, you don’t have to fully qualify it for the program to work.

Maybe I understand what you are saying, but if so, does that mean that in the default program, WriteLine is in the Console namespace?

Excellent observation! The answer is no, but I see why you would say that. Honestly, the answer to your question should really be the topic of another post. For now though, if you want to use it in your program, you do have to fully qualify it as it is in a different namespace. The way you would do that would be to call it as follows System.Console.WriteLine("Hello World!");. A topic for another time will be how the program above is able to call it not fully qualified. The answer lies in the using System; statement, but will have to wait for another time.

Wow, that was a lot. To be honest, I’m a little overwhelmed at the moment.

Don’t fret. That is very normal. As you continue to progress in your education and employment, you will find that there is so much to know that no one knows it all. The goal is to be continually growing and building that knowledge base to allow you to continue tackling bigger and harder ‘automation’ problems.

As mentioned previously, there are a number of tools out there to help with writing C# code. The easiest place to get started is provided by Microsoft. In that document, they list tools, with links on how to get them installed, for every operating system. Take a look, get one installed and be ready to start writing your first program in the next post.

Until next time!