A given assembly may contain any number of distinct types. In the world of .NET, type is simply a
general term used to refer to a member from the set {class, interface, structure, enumeration, delegate}.
When you build solutions using a .NET-aware language, you will most likely interact with
many of these types. For example, your assembly may define a single class that implements some
number of interfaces. Perhaps one of the interface methods takes an enumeration type as an input
parameter and returns a structure to the caller.
Recall that the CTS is a formal specification that documents how types must be defined in
order to be hosted by the CLR. Typically, the only individuals who are deeply concerned with the
inner workings of the CTS are those building tools and/or compilers that target the .NET platform.
It is important, however, for all .NET programmers to learn about how to work with the five types
defined by the CTS in their language of choice. Here is a brief overview.
CTS Class Types
Every .NET-aware language supports, at the very least, the notion of a class type, which is the cornerstone
of object-oriented programming (OOP). A class may be composed of any number of
members (such as properties, methods, and events) and data points (fields). In C#, classes are
declared using the class keyword:
// A C# class type.
class Calc
{
public int Add(int x, int y)
{ return x + y; }
}
CTS Interface Types
Interfaces are nothing more than a named collection of abstract member definitions, which may be
supported (i.e., implemented) by a given class or structure. Unlike COM, .NET interfaces do not
derive a common base interface such as IUnknown. In C#, interface types are defined using the
interface keyword, for example:
// A C# interface type is usually
// declared as public, to allow types in other
// assemblies to implement their behavior.
public interface IDraw
{
void Draw();
}
On their own, interfaces are of little use. However, when a class or structure implements a given
interface in its unique way, you are able to request access to the supplied functionality using an
interface reference in a polymorphic manner.
CTS Structure Types
The concept of a structure is also formalized under the CTS. If you have a C background, you should
be pleased to know that these user-defined types (UDTs) have survived in the world of .NET (although
they behave a bit differently under the hood). Simply put, a structure can be thought of as a lightweight
class type having value-based semantics. For more details on the subtleties of structures, Typically, structures are best suited for modeling geometric and mathematical data, and
are created in C# using the struct keyword:
// A C# structure type.
struct Point
{
// Structures can contain fields.
public int xPos, yPos;
// Structures can contain parameterized constructors.
public Point(int x, int y)
{ xPos = x; yPos = y;}
// Structures may define methods.
public void Display()
{
Console.WriteLine("({0}, {1}", xPos, yPos);
}
}
CTS Enumeration Types
Enumerations are handy programming constructs that allow you to group name/value pairs. For
example, assume you are creating a video-game application that allows the player to select one of
three character categories (Wizard, Fighter, or Thief). Rather than keeping track of raw numerical
values to represent each possibility, you could build a custom enumeration using the enum keyword:
// A C# enumeration type.
enum CharacterType
{
Wizard = 100,
Fighter = 200,
Thief = 300
}
By default, the storage used to hold each item is a 32-bit integer; however, it is possible to alter
this storage slot if need be (e.g., when programming for a low-memory device such as a Pocket PC).
Also, the CTS demands that enumerated types derive from a common base class, System.Enum. this base class defines a number of interesting members that allow you to
extract, manipulate, and transform the underlying name/value pairs programmatically.
CTS Delegate Types
Delegates are the .NET equivalent of a type-safe C-style function pointer. The key difference is that a
.NET delegate is a class that derives from System.MulticastDelegate, rather than a simple pointer to
a raw memory address. In C#, delegates are declared using the delegate keyword:
// This C# delegate type can "point to" any method
// returning an integer and taking two integers as input.
delegate int BinaryOp(int x, int y);
Delegates are useful when you wish to provide a way for one entity to forward a call to another
entity, and provide the foundation for the .NET event architecture. delegates have intrinsic support for multicasting (i.e., forwarding a request to multiple
recipients) and asynchronous method invocations.
CTS Type Members
Now that you have previewed each of the types formalized by the CTS, realize that most types take
any number of members. Formally speaking, a type member is constrained by the set {constructor,
finalizer, static constructor, nested type, operator, method, property, indexer, field, read-only field,
constant, event}.
The CTS defines various “adornments” that may be associated with a given member. For example,
each member has a given visibility trait (e.g., public, private, protected, and so forth). Some
members may be declared as abstract to enforce a polymorphic behavior on derived types as well as
virtual to define a canned (but overridable) implementation. Also, most members may be configured
as static (bound at the class level) or instance (bound at the object level). The construction of
type members is examined over the course of the next several chapters.
nNote, the C# language also supports the construction of generic types and generic
members.
Intrinsic CTS Data Types
The final aspect of the CTS to be aware of for the time being is that it establishes a well-defined set
of fundamental data types. Although a given language typically has a unique keyword used to
declare an intrinsic CTS data type, all language keywords ultimately resolve to the same type
defined in an assembly named mscorlib.dll.
data types are expressed in various .NET languages.
The Intrinsic CTS Data Types
CTS Data Type VB .NET Keyword C# Keyword C++/CLI Keyword
System.Byte Byte byte unsigned char
System.SByte SByte sbyte signed char
System.Int16 Short short short
System.Int32 Integer int int or long
System.Int64 Long long __int64
System.UInt16 UShort ushort unsigned short
System.UInt32 UInteger uint unsigned int or unsigned long
System.UInt64 ULong ulong unsigned __int64
System.Single Single float Float
System.Double Double double Double
System.Object Object object Object^
System.Char Char char wchar_t
System.String String string String^
System.Decimal Decimal decimal Decimal
System.Boolean Boolean bool Bool
Given the fact that the unique keywords of a managed language are simply shorthand notations
for a real type in the System namespace, we no longer have to worry about overflow/underflow
conditions for numerical data, or how strings and Booleans are internally represented across different
languages. Consider the following code snippets, which define 32-bit numerical variables in C#
and VB .NET, using language keywords as well as the formal CTS type:
// Define some "ints" in C#.
int i = 0;
System.Int32 j = 0;
' Define some "ints" in VB .NET.
Dim i As Integer = 0
Dim j As System.Int32 = 0
No comments:
Post a Comment