Description: This document is a tutorial in a series of
tutorials for programmers learning about the .NET Framework development
environment. What you will learn is what
C# is, as well as how to be a successful object oriented programmer with C#.
Requirements: You should be familiar with at least one programming language, such as C++, Pascal, PERL, Java or Visual Basic. You should have some comfort with object oriented concepts such as instantiating and using objects. You should be comfortable with general computer science concepts. To do the exercises and run the examples you need a PC running Windows with the .NET Framework installed.
1 Writing
Object Oriented Software with C#
2 Object
Oriented Concepts (A Refresher)
2.5 Members
and Basic Accessibility
6 Operator
Overloading and Type Conversion
6.2 Casting
Operators (type converters)
Figure
2‑1 Types and Instances
Figure
3‑1 Point.cs Property Example
Figure
3‑2 Instance Constructors
Figure
3‑3 Accessibility Modifiers
Writing Object Oriented Software with C#
The .NET Framework is a new platform designed to target the Internet. The .NET framework is also an object-oriented platform from the ground up. And you most likely already know that C# is one of the most popular language choices for programming .NET or managed software.
In the last tutorial in this series I introduced C# with some code samples, a discussion of syntax, and a briefer on how to get your C# programs written and built. In this tutorial, we will take this information a step further and pursue C# as a best-of-breed object oriented programming language.
I love the ideas behind object oriented programming. The concepts are sound, and from time to time the implementations are just as sound. But the fact remains that many mainstream programming languages are less than pure in their approach to OO. C# is not one of these languages.
First things first, the API (application programmer interface) that C# uses to do stuff is called the Framework Class Library. The Framework Class Library is a huge library of objects meant for use in your managed code. C# and managed code in general really has only one way to gain access to underlying features of its host OS and that is through objects.
Second, C# is a first class citizen in the discipline of creating objects. C# comes complete with the basics, such as the ability to create classes of objects, abstract data, implement polymorphism and the like. C# extends these abilities with some nice bells and whistles such as properties, operator overloading, and built in event-handling constructs.
Third, the marriage of points one and two are surprisingly successful. The objects in the FCL are designed to be extended, and C# is a great language to use to make these derivations. The more I develop in C#, the more I notice that my applications are largely made of objects that extend objects in the FCL; meanwhile my application-only code is becoming increasingly terse. In fact much of my code fits-in so well with the objects in the FCL that they are hard to distinguish. This is a good progression and leads to more flexible software in general.
The remainder of this tutorial is almost completely dedicated to describing the features of C# as it pertains to object oriented programming. I am not going to attempt any major discussion on approach or design. But I do want to take a quick side-trip through some OO terms just to make sure that our terminology is in sync.
The basic goals of Object Oriented (OO) programming are simple. One is to hide complexity by abstracting data behind a wall of methods or functionality. The second (and this is related) is to group data with the code that manipulates the data. The third is modularity; the ability plug-in and un-plug code modules is very important.
One means of reaching these goals is the creation of classes of objects. These classes of objects are often called classes, but for the remainder of this tutorial I am going to refer to classes of objects as types, and then when I address specific varieties of types I will use specific terms like class, structure, or enumerated type.
Another means of reaching the OO goals is through type derivation and polymorphism. These features help you as a programmer to realize the goal of code modularity.
The basic ideas are simple, but the implementations vary a
lot, and so there is much to learn.
As an object oriented programmer you will first and foremost create instances of types. This means that you will use a definition for a type, which has a name such as String or ArrayList, to create an actual object in memory. This object is structured based on the details described in the type’s definition.
After you have created an object, you can use it by calling methods and/or referencing fields on the object. When you are finished with the object it must be cleaned up. Is some environments you do this explicitly; in others, such as C# or Java, cleanup is done for you by the system.
Creating instances is a nice introduction to OO programming, but eventually you will have to define your own type. By doing so you create a new classification for a kind of object that can be created. You give the type a name, and you create members of the type such as methods and fields.
It is important to distinguish between types and instances, so I will make an analogy. Think of the type as a descriptive tool (like a cookie cutter), while an instance is an object created from that description (in the same way that a cookie is created from a cookie cutter).

Figure 1‑1 Types and Instances
Finally, the process of using a type to create an object is
called instantiation. In C#, C++, and Java the new keyword is used to instantiate an object. Sometimes I will use the conversational term,
“new-up” to indicate an instantiation.
Most object oriented languages allow you to derive a type from another existing type. (In fact C# and Java both require a type to be derived from a base type). When a type is derived from another type it becomes an extension of the base type. As an extension it inherits with it all of the features and functionality of the base type, and most likely has some new features added.
If type Automobile is derived from type Machine, then type Machine is the base class or base type in the relationship. Conversely, type Automobile would be the derived type, or derived class. Because of derivation, types exist in a logical derivation hierarchy.

Figure 1‑2
Derivation
From the computer’s point of view, objects are data. They are the culmination of their fields and enough information to indicate their type. Often this data is complex and sizeable, and it is stored in the memory heap of the program that created the instance.
Because objects so often live in the heap-memory of a program, the most common way of dealing with an instance is through a reference variable. The reference variable can be a global or local variable, or it can be a field in another object. Either way, there are some rules of reference variables.
Reference variables have a type associated with them. For every object-type defined in an object oriented system, there is a matching reference variable type that is used to refer to instances of the type.
Reference variables can refer to an instance or object, or they can refer to null (in most OO languages anyway). A null reference simply indicates that this variable does not refer to any object, but could have an object reference assigned to it.
Reference variables do not always refer to objects of the exact same type as the reference variable. This can be confusing, but in fact the rules are simple. A reference variable must refer to an object of matching type or it must refer to an object that is ultimately derived from the matching type.
Looking back to the relationship between Automobile and Machine, a reference variable of type Automobile can only refer to an instance of Automobile; however a reference variable of type Machine can refer to an instance of Machine or an instance of Automobile. You can look at this as being possible, because Automobile is a Machine through the affect of derivation.
Reference variables are your means of access to an object or instance. What this means is that you use the reference variable to touch fields of the object and you use the reference variable to call methods on the object. There are two related rules of reference variables that make the most sense when stated together.
· Regardless of what type of instance your reference variable refers to, it is the type of the variable that constrains how you can touch or affect the instance.
·
Regardless of what type of reference variable
you are using to refer to an object, the type of the object never changes for
the life of the object.
Polymorphism is closely related to type-derivation and reference variables. But it is an advanced topic, and can be difficult to describe. The goal is to allow a generic piece of code to work with objects or instances generically; meanwhile we want the objects themselves to do the right thing based on their respective types.
An example of this would be a piece of code that iterates over an array of references to Automobile objects.