Datasheet

did not permit implementation inheritance, which meant that it lost many of the advantages of object-
oriented programming.
An associated problem was that, when debugging, you would still have to debug components written
in different languages independently. It was not possible to step between languages in the debugger. So
what we really mean by language interoperability is that classes written in one language should be able
to talk directly to classes written in another language. In particular:
A class written in one language can inherit from a class written in another language.
The class can contain an instance of another class, no matter what the languages of the two
classes are.
An object can directly call methods against another object written in another language.
Objects (or references to objects) can be passed around between methods.
When calling methods between languages you can step between the method calls in the debugger,
even when this means stepping between source code written in different languages.
This is all quite an ambitious aim, but amazingly, .NET and IL have achieved it. In the case of stepping
between methods in the debugger, this facility is really offered by the Visual Studio .NET integrated
development environment (IDE) rather than by the CLR itself.
Distinct Value and Reference Types
As with any programming language, IL provides a number of predefined primitive data types. One char-
acteristic of IL, however, is that it makes a strong distinction between value and reference types. Value
types are those for which a variable directly stores its data, whereas reference types are those for which a
variable simply stores the address at which the corresponding data can be found.
In C++ terms, using reference types can be considered to be similar to accessing a variable through a
pointer, whereas for Visual Basic, the best analogy for reference types are objects, which in Visual Basic 6
are always accessed through references. IL also lays down specifications about data storage: instances of
reference types are always stored in an area of memory known as the managed heap, whereas value types
are normally stored on the stack (although if value types are declared as fields within reference types, they
will be stored inline on the heap). Chapter 2, “C# Basics,” discusses the stack and the heap and how
they work.
Strong Data Typing
One very important aspect of IL is that it is based on exceptionally strong data typing. That means that all
variables are clearly marked as being of a particular, specific data type (there is no room in IL, for example,
for the
Variant data type recognized by Visual Basic and scripting languages). In particular, IL does not
normally permit any operations that result in ambiguous data types.
For instance, Visual Basic 6 developers are used to being able to pass variables around without worrying
too much about their types, because Visual Basic 6 automatically performs type conversion. C++ devel-
opers are used to routinely casting pointers between different types. Being able to perform this kind of
operation can be great for performance, but it breaks type safety. Hence, it is permitted only under certain
9
Chapter 1: .NET Architecture
24727c01.qxd:WroxPro 5/7/07 12:12 PM Page 9