Dictionary Assignment C# Employee Introduction To Classes And Objects

Get GitHub Code

In previous lessons, the topic of "classes" and "objects" has been mentioned, but not detailed. The reason for this is because this topic has to do with Object-Oriented Programming (or “OOP”), which is a shift in thinking that takes time to really understand its significance. OOP takes the basic concepts you already understand (variables, methods, scope) and separates them into a more conceptual framework; grouping one set of variables and methods in one class and grouping others in another, for example. And from those classes you can build “instances” that are bound up in a special kind of variable called an object. Those objects then work together as communities to solve problems. Objects (and therefore, classes) have a host of special properties that we have yet to see. They can inherit from other classes in order to add functionality and create a more flexible software system, as well as reducing the amount of dependency in your system. Dependency becomes a problem when one piece of code breaks, causing another piece of code that is dependent on it to break as well. Classes are an important step towards reducing dependency and allowing you to enforce the “separation of concerns” principle we spoke of earlier.


By keeping code as separate as possible, using various object-oriented techniques, you are de-coupling dependencies within your code. Coupling is most glaring when you are debugging and start to notice how “whacking” a bug in one part of your code causes another bug to “pop up” elsewhere. And if it only happens under certain runtime conditions, you have the makings for a real coding nightmare.

Step 1: Distinguishing OOP and Procedural Programming Styles

To distinguish OOP from non-OOP you could contrast it with the style of programming we have been mostly doing up to this point which is based on a procedural style. This is an old style of programming where you work in terms of data in/data out. This style of programming typically uses carefully named variables and methods to represent data points and processes. These data points might be loosely coupled together - perhaps by some kind of naming convention - but the main distinction is that we haven’t been thinking of the data as a representative piece of a larger architecture. And beyond the problem-solving logic, we haven’t considered maintainability or how change introduced within the system will affect the existing code, such as new requirements or functionality introduced later on. We also haven’t really worried about reusability of code we've already written for use in another project.

Step 2: Why Bother Learning OOP?

In contrast to the procedural style of programming detailed above, OOP prioritizes interaction of objects throughout their creation. In other words, when we think in terms of objects that need to talk to other objects in order to accomplish a solution as a piece within a broader problem, we are putting a priority on all of these elements that procedural programming doesn’t concern itself with. This added complexity often leaves beginners wondering if this higher layer of concern – beyond just solving the problem – is worthwhile for the average programmer, especially considering that most beginning applications are actually quite simple. What you will come to learn is that the conceptual nature of OOP eventually allows you to create more complex applications without the burden of confronting their complexity upfront. OOP ultimately allows you to concern yourself less with mundane issues, instead abstracting them away into nice little bundles that you rarely have to look at and understand in full. It will allow you to focus better on individual problems that need solving, within a broader puzzle, and in the software development world there is always a broader puzzle.


The subject of Object-Oriented-Programming is both relatively easy to pick up on and extremely deep if you want to continue pursuing it. It can take time to fully understand, and appreciate, how much it offers. Don't feel bad if you don't really understand it all the first time through. The best way to look at learning OOP is its return on time investment: the relatively modest amount of extra time you put in now to learn its secrets pales in comparison to the time you gain back when using it to build robust and extensible applications. Just keep working through the examples over the next few lessons and you will eventually start seeing the world of code around you as made up of objects.

Step 3: You’ve Already Been Doing OOP without Realizing It

Virtually everything in C# - including the part of the .NET Framework that deals with ASP.NET functionality – is either a class, or part of a class. In all of the previous lessons, we have been using ASP.NET Web Forms with a Default.aspx file. What you may not have realized is we were just creating a class definition – a set of methods and properties for a class - in that file.

What you haven’t yet seen is that the ASP.NET Runtime will create an instance of this Default class whenever the user requests it over the internet. Once it creates an instance of that class, it will begin calling methods or setting/retrieving properties of that class. Part of that process is being determined by what you write in the code for this Default class. In case you are wondering, the ultimate responsibility for this class is to generate HTML that represents a webpage called “default.”

The purpose of this lesson and the next few lessons is simply to understand classes and their ubiquity when working with C#.

Step 4: Create a New Project

For this lesson, suppose that you wanted to create an application that works with cars in some way. You may have a car lot with an inventory of all the cars that are for sale, or you may want to keep related information about a single car in one container. That container can be created using a class, and allows you to keep all of this related information that represents a car within the class.

Begin by creating a new ASP.NET project with a single Server Control resultLabel:

In Default.aspx.cs, create a new class called Car alongside the Default class, keeping both classes within the broader “CS-ASP_036” namespace:

Step 5: Methods and Properties as Class Members

What we’re doing here is naming a code-block (“Car”) similar to how methods are named blocks of code that perform some particular process, we can later reference classes as we do with any variable or method, setting or retrieving their properties. Within this code block, we have two basic “members” that immediately belong to it and those members are typically variables (properties) and methods. Class-level properties are much like any variable we have worked with thus far, but are usually meant to describe attributes common to that object’s class. For example, a car is typically defined by properties such as:

  • Make

  • Model

  • Year Built

  • Color

Class-level methods also define something about the class, and that is what the class can do (tasks, processes, behaviors, actions, and so on). A car can among other things do things such as:

Step 6: Understanding Properties

In this sense, classes often are created to model - insofar as it’s important to the functioning of our application - the behavior and physical properties of their real-world counterparts. Let’s start off by adding the following properties to this class:

Notice that these are just like ordinary variables – with a type, and an identifier – except for the accessibility prefix (in this case, public) as well as the get; and set; postfix, which can be seen as the read/write attributes. You can access the code snippet for this by typing in “prop” and hitting the tab key twice:

Step 7: Objects as Class Instances

Now, to create an instance or actual object of our car in code we can do so by referencing the class as we do any variable type:

By creating an instance of the class we’ve defined, you can look at it like the class is a blueprint, while the object instance is the actual object itself from that blueprint. And just like a blueprint can be reused to create several objects in the real world, you can do so as well with blueprints and objects in code:

Each instance can now have its own unique values for its properties that you can set as you would any variable:

Step 8: Understanding Object Instances in Memory

Each individual value is stored in sections of memory, while another section of memory hold onto myNewCar as a reference to these memory sections and their values:

Now that you have an instance of a Car in memory, with its included properties, you can get those values in memory (again, just like any ordinary variable):

Since Car is a type all its own, you can use it and reference it anywhere. For instance, as an input parameter in a method:

Step 9: Using Your Custom Class as Any Other Type

Notice here that the variable identifier (name) is the same as the type, except that has a different casing. This is perfectly acceptable – even if they share the exact same casing – as the compiler can distinguish between the object’s name and its type. Also, notice that the input parameter is not used in this method, however, you would want to make use of the input parameter in a real-world example. But for the sake of brevity imagine that this method is doing something useful with the information we have about the car that we supply as an input argument at the method call:

And now you can add the value returned into myMarketValueofCar to the resultLabel:

To make this a bit more interesting, let’s actually show how you would go about referencing the input parameter within the method body for determineMarketValue() to modify the result depending on the age of the car:

Step 10: Using Classes to Maintain Separation of Concerns

If you think back to what was said in previous lessons about “Separation of Concerns” it seems that the determineMarketValue() method violates this principle somewhat. In specific, it’s a method that calculates the value of a car, so putting it in the Default class (which is about rendering web page data) is a bit off the mark. Let’s transplant this method to the Car class, where it conceptually fits in a bit better, but with some modifications first:

  1. Change the accessibility to “public,” so that outside classes can call this method.

  2. Remove the input parameter as it is no longer required.

  3. Directly reference the Year property, now that the method can “reach-out” of its scope and reference it at the class-level.

Step 11: Using the Dot Accessor To Reference Instance Members

Now that the method belongs to the Car class, we will have to reference it through the Car instance in outside classes, just as we would the Car properties:


As you’ve seen, you can use the dot accessor (period) to peer into a class containment, in order to get/set properties or call methods. In later lessons you will see how class properties can, themselves, be instances of other classes. This creates multiple levels of containment that can be accessed by using multiple dot accessors; peering through one containment level after another.

All the way back in Lesson 02, you learned about arrays and how they allow you to add and retrieve a collection of objects. Arrays are good for many tasks, but C# v2.0 introduced a new feature called generics. Among many benefits, one huge benefit is that generics allow us to create collections that allow us to do more than allowed by an array. This lesson will introduce you to generic collections and how they can be used. Here are the objectives for this lesson:

  • Understand how generic collections can benefit you
  • Learn how to create and use a generic List
  • Write code that implements a generic Dictionary

What Can Generics Do For Me?

Throughout this tutorial, you’ve learned about types, whether built-in (int, float, char) or custom (Shape, Customer, Account). In .NET v1.0 there were collections, such as the ArrayList for working with groups of objects. An ArrayList is much like an array, except it could automatically grow and offered many convenience methods that arrays don’t have. The problem with ArrayList and all the other .NET v1.0 collections is that they operate on type object. Since all objects derive from the object type, you can assign anything to an ArrayList. The problem with this is that you incur performance overhead converting value type objects to and from the object type and a single ArrayListcould accidentally hold different types, which would cause hard to find errors at runtime because you wrote code to work with one type. Generic collections fix these problems.

A generic collection is strongly typed (type safe), meaning that you can only put one type of object into it. This eliminates type mismatches at runtime. Another benefit of type safety is that performance is better with value type objects because they don’t incur overhead of being converted to and from type object. With generic collections, you have the best of all worlds because they are strongly typed, like arrays, and you have the additional functionality, like ArrayList and other non-generic collections, without the problems.

The next section will show you how to use a generic List collection.

Creating Generic List<T> Collections

The pattern for using a generic List collection is similar to arrays. You declare the List, populate its members, then access the members. Here’s a code example of how to use a List:

List<int> myInts = new List<int>(); myInts.Add(1); myInts.Add(2); myInts.Add(3); for (int i = 0; i < myInts.Count; i++) { Console.WriteLine("MyInts: {0}", myInts[i]); }

The first thing you should notice is the generic collection List<int>, which is referred to as List of int. If you looked in the documentation for this class, you would find that it is defined as List<T>, where T could be any type. For example, if you wanted the list to work on string orCustomer objects, you could define them as List<string> or List<Customer> and they would hold only string or Customer objects. In the example above, myInts holds only type int.

Using the Add method, you can add as many int objects to the collection as you want. This is different from arrays, which have a fixed size. The List<T> class has many more methods you can use, such as Contains, Remove, and more.

There are two parts of the for loop that you need to know about. First, the condition uses the Count property of myInts. This is another difference between collections and arrays in that an array uses a Length property for the same thing. Next, the way to read from a specific position in the List<T> collection, myInts[i], is the exact same syntax you use with arrays.

The next time you start to use a single-dimension array, consider using a List<T> instead. That said, be sure to let your solution fit the problem and use the best tool for the job. i.e. it’s common to work with byte[] in many places in the .NET Framework.

Working with Dictionary<TKey, TValue> Collections

Another very useful generic collection is the Dictionary, which works with key/value pairs. There is a non-generic collection, called aHashtable that does the same thing, except that it operates on type object. However, as explained earlier in this lesson, you want to avoid the non-generic collections and use thier generic counterparts instead. The scenario I’ll use for this example is that you have a list ofCustomers that you need to work with. It would be natural to keep track of these Customers via their CustomerID. The Dictionary example will work with instances of the following Customer class:

publicclass Customer { public Customer(int id, string name) { ID = id; Name = name; } privateint m_id; publicint ID { get { return m_id; } set { m_id = value; } } privatestring m_name; publicstring Name { get { return m_name; } set { m_name = value; } } }

The Customer class above has a constructor to make it easier to initialize. It also exposes its state via public properties. It isn’t very sophisticated at this point, but that’s okay because its only purpose is to help you learn how to use a Dictionary collection.  The following example populates a Dictionary collection with Customer objects and then shows you how to extract entries from the Dictionary:

Dictionary<int, Customer> customers = new Dictionary<int, Customer>(); Customer cust1 = new Customer(1, "Cust 1"); Customer cust2 = new Customer(2, "Cust 2"); Customer cust3 = new Customer(3, "Cust 3"); customers.Add(cust1.ID, cust1); customers.Add(cust2.ID, cust2); customers.Add(cust3.ID, cust3); foreach (KeyValuePair<int, Customer> custKeyVal in customers) { Console.WriteLine( "Customer ID: {0}, Name: {1}", custKeyVal.Key, custKeyVal.Value.Name); }

The customers variable is declared as a Dictionary<int, Customer>.  Considering that the formal declaration of Dictionary isDictionary<TKey, TValue>, the meaning of customers is that it is a Dictionary where the key is type int and the value is type Customer. Therefore, any time you add an entry to the Dictionary, you must provide the key because it is also the key that you will use to extract a specified Customer from the Dictionary.

I created three Customer objects, giving each an ID and a Name. I’ll use the ID as the key and the entire Customer object as the value. You can see this in the calls to Add, where custX.ID is added as the key (first parameter) and the custX instance is added as the value (second parameter).

Extracting information from a Dictionary is a little bit different. Iterating through the customersDictionary with a foreach loop, the type returned is KeyValuePair<TKey, TValue>, where TKey is type int and TValue is type Customer because those are the types that thecustomersDictionary is defined with.

Since custKeyVal is type KeyValuePair<int, Customer> it has Key and Value properties for you to read from. In our example,custKeyVal.Key will hold the ID for the Customer instance and custKeyVal.Value will hold the whole Customer instance. The parameters in the Console.WriteLine statement demonstrate this by printing out the ID, obtained through the Key property, and the Name, obtained through the Name property of the Customer instance that is returned by the Value property.

The Dictionary type is handy for those situations where you need to keep track of objects via some unique identifier. For your convenience, here’s Listing 20-1, shows how both the List and Dictionary collections work.

Listing 20-1. Introduction to Using Generic Collections with an Example of the List<T> and Dictionary<TKey, TValue> Generic Collections
using System; using System.Collections.Generic; publicclass Customer { public Customer(int id, string name) { ID = id; Name = name; } privateint m_id; publicint ID { get { return m_id; } set { m_id = value; } } privatestring m_name; publicstring Name { get { return m_name; } set { m_name = value; } } } class Program { staticvoid Main(string[] args) { List<int> myInts = new List<int>(); myInts.Add(1); myInts.Add(2); myInts.Add(3); for (int i = 0; i < myInts.Count; i++) { Console.WriteLine("MyInts: {0}", myInts[i]); } Dictionary<int, Customer> customers = new Dictionary<int, Customer>(); Customer cust1 = new Customer(1, "Cust 1"); Customer cust2 = new Customer(2, "Cust 2"); Customer cust3 = new Customer(3, "Cust 3"); customers.Add(cust1.ID, cust1); customers.Add(cust2.ID, cust2); customers.Add(cust3.ID, cust3); foreach (KeyValuePair<int, Customer> custKeyVal in customers) { Console.WriteLine( "Customer ID: {0}, Name: {1}", custKeyVal.Key, custKeyVal.Value.Name); } Console.ReadKey(); } }

Whenever coding with the generic collections, add a using System.Collections.Generic declaration to your file, just as in Listing 20-1.


Generic collections give you the best of all worlds with the strong typing of arrays and flexibility of non-generic collections. There are many more generic collections to choose from also, such as Stack, Queue, and SortedDictionary. Look in the System.Collections.Genericnamespace for other generic collections.

I invite you to return for Lesson 21: Anonymous Methods.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

0 thoughts on “Dictionary Assignment C# Employee Introduction To Classes And Objects

Leave a Reply

Your email address will not be published. Required fields are marked *