The .NET Common Programming Model (CPM) allows different languages to employ the .NET framework. In this article, I’ll offer an overview of the basic ideas behind CPM. I’ll discuss how CPM is used by VB .NET and C#, and see how similar syntax can be used with other languages that support the .NET CLR (Common Language Runtime).
The Idea: Common Objects
A fundamental idea behind .NET programming is the idea of Common Objects—objects that are accessible anywhere, anytime, and from any device. This is accomplished through standard object oriented programming (OOP) concepts. Among these are namespace, inheritance, and polymorphism.
An object is a bit of code you can reference through a specific word. For instance, if you want to refer to an object of type Automobile, you could call it MyCar by using this line of C# code:
Automobile MyCar = new Automobile();
Next, you access all methods exposed by the Automobile class, as implemented in the MyCar instance of the object. You could check the value of MyCar.FuelLevel or its location through the MyCar.LoJack property, or start the car with the MyCar.StartEngine() method.
As you saw in each of the MyCar examples, by having a common object (or Class) from which to derive your objects, you can create multiple, manageable instances of the same new type of object, and have a common model from which you can derive similar functions. Now, let’s take a closer look at the object-oriented principles behind CPM—beginning with the namespace.
The idea of a namespace as it relates to an object model is that everything should have a “name” and, more importantly, that no two objects have the same name. When you refer to an object name in code, there's no mistaking which one is being referenced.
The idea of unique names would seem obvious, yet cases of “namespace collisions” pop up all the time. For instance, according to the .NET Platform SDK, if your application installs a file called SCardCOM.dll onto a system, it can screw up other programs that rely on SmartCard technology because of a name collision.
In OOP, a class derived from another class is called a child class. Inheritance is the idea that a child class can “inherit” from its parent. In code, inheritance means that if you create a class called Automobile and give it methods like StartEngine and TurnOnLights and objects like Engine and AirConditioner, all objects derived from the Automobile class would “inherit” these other objects and methods. You could create objects derived from the Automobile class, such as MyCar, YourCar, and HisCar.
Polymorphism is the ability to “override” the inherited methods of a class. For instance, if you have two classes that are derived from Automobile, one called ManualTransmission and another called AutomaticTransmission, you’ll want to override the StartEngine method to include making sure that the transmission is in Park or Neutral, as necessary.
Now I'll turn to actual features of the .NET environment.
The model: System.Object
The System.Object is the basic definition of every object in the .NET Framework. All other objects derive from this one fundamental class. All of those objects must provide four public methods: Equals(), GetHashCode(), GetType(), and ToString(). Let’s take a closer look at each method.
The Equals() method is used to compare two objects. It returns a Boolean value (true/false). If you were to compare a String class with the text “Hello” to a StringBuilder class with the same text, it would return a false. However, if you compare two classes, each of the same type and ofequal value, this method will return “true.” You need the Equals() method in a .NET class to determine if a particular instance of an object is the same as another.
The GetHashCode() method is used to uniquely identify an instance of an object. This uniqueness is managed by .NET, but with one quirk—if the object you're using will be part of an array of similar objects, you'll need to override this method and use your own algorithm for determining uniqueness. The reason you need a hash code is so that you can have several instances of your class (e.g., “Contact”) gathered together in a collection (e.g., “Contacts”).
The GetType() method returns a string value that identifies the type of object that is being queried. It doesn’t identify the particular object, however—just its type. To uniquely identify an instance of an object, you need to use the GetHashCode() method.
You'd use the GetType() method to be sure of the type of object you're dealing with. You can also use the GetMethods() method of the GetType() method to find out what other methods are supported. Thus, no matter what language the class was created in, its methods can be identified, and then used by, any other language.
The ToString() method returns a text string from the object. For instance, calling ToString() on a String object would return the value of the string. However, the default behavior of the function is to return a string value indicating the current string representation of the object. If you had an object called MyCar.Engine and called ToString() on that object (i.e., x = MyCar.Engine.ToString()), it would return the value MyCar.Engine.
There are a couple of reasons to use this method. One is for debugging purposes. You could use it to make sure that you're dealing with the object you think you are. The other reason is for messaging. For example, you may have an object called ThatWebPage(). You could run ThatWebPage.ToString() to retrieve the entire HTML content of the page into one big string.
Alternate .NET languages
The .NET platform is not restricted to VB. NET and C# developers. Click here to read more about this exciting new feature from Microsoft.
One of the reasons that .NET CPM-based components are easy to use with other languages is that the syntax remains relatively the same from one language to the next. For instance, in our sample object, MyCar, all of the methods are addressed the same way in each language—object.method (e.g., MyCar.Engine, MyCar.StartEngine).
Some aspects still rely on the specific language. For instance, in C# we use the “using” directive to reference the “System” object. However, VB .NET, Perl .NET, and other languages may reference it differently.
Regardless of minor differences like this, after the language knows it's using a CPM-based component, usage within the code of each language is the same.
The four public methods described above can be seen in C# in Listing A.
This demonstrates the four methods required of every application that runs within the Common Programming Model.