Search - Articles - Dev Forums - Favorites - Member Login  
DevASP.NET for ASP.NET, VB.NET, XML and C# (C-Sharp) Developers Friday, September 03, 2010

Dev Articles
Search Directory
ASP.NET
VB.Net
C-Sharp
SQL Server
 

A Sample Chapter from C# Programmers Reference



Value types

Value types represent primitive values such as integers or floating-point values. There are three general categories of value types: enumerations, which are described in detail in Chapter 10; built-in value types; and user-defined value types, or structs. As we have seen, value types store their data directly on the stack. Since parameters are by default passed by value in C#, when a value-type parameter is passed into a method, a new copy of the value is created; any changes made to the parameter won't result in changes to the variable passed into the method. Method parameters are discussed in detail in Chapter 12.

Built-in value types

The .NET Framework provides a number of predefined value types. These represent various integer, floating point, character, and Boolean values. In other programming languages these are often referred to as primitive data types. The built-in data types of the .NET Framework are defined as structures and can be found in the System namespace. A list of the built-in value types available in C# is given below:


 

Struct Name

C# Alias

IL Alias

CLS-
Compliant

Description

Range

Boolean

bool

bool

Yes

Boolean value

true or false

Byte

byte

unsigned int8

Yes

8-bit unsigned integer

0 to 255

Char

char

char

Yes

16-bit Unicode character

 

Decimal

decimal

(Not an IL primitive type)

Yes

128-bit high precision

±1.0E-28 to ±7.9E+28 (and 0.0) decimal notation

Double

double

float64

Yes

64-bit double precision floating point

±5.0E-324 to ±1.7E+308 (and 0.0) floating point number

Int16

short

int16

Yes

16-bit signed integer

-32768 to 32767

Int32

int

int32

Yes

32-bit signed integer

-2,147,483,648 to 2,147,483,647 (-2.15E+9 to 2.15E+9)

Int64

long

int64

Yes

64-bit signed integer

-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (-9.22E+18 to 9.22E+18)

SByte

sbyte

int8

No

8-bit signed integer

-128 to 127

Single

float

float32

Yes

32-bit single precision floating point

±1.5E-45 to ±3.4E+38 (and 0.0) floating point number

UInt16

ushort

unsigned int16

No

16-bit unsigned integer

0 to 65535

UInt32

uint

unsigned int32

No

32-bit unsigned integer

0 to 42,949,667,295 (0 to 4.29E+9)

UInt64

ulong

unsigned int64

No

64-bit unsigned integer

0 to 18,446,744,073,709,551,615 (0 to 1.84E+19)

IntPtr

native int

Yes

Signed integer of a platform-specific size (for example 32-bit on a 32-bit system)

(Platform-specific)

UIntPtr

native unsigned int

No

Unsigned integer of a platform-specific size

(Platform-specific)

Typed
Reference

typedref

No

Pointer to a memory location where data is stored, together with a representation of the type stored at that location

 

 


Notice that decimal is treated here as a primitive, since it has a C# alias, although it is actually a composite type when compiled to IL. The last three types (IntPtr, UIntPtr, and TypedReference) are primitive types in IL, but don't have C# aliases, and can't be instantiated using a normal assignment; instead we need to use the types' constructors or other keywords.

Platform-specific integers

The two platform-specific integral types, IntPtr and UIntPtr, are used for native resources such as window handles. The size of such resources will vary according to the hardware and operating system in use, but will always be big enough to hold a pointer on the system (hence the name). For example, to retrieve the handle for a Windows Form we can use:

 

IntPtr hWnd = this.Handle;

 

Note that IntPtr is CLS-compliant, but the unsigned equivalent, UIntPtr, is not.

Typed references

The last type – TypedReference – is by far the least common, and its use is poorly documented, so we'll take a moment to look at it. It represents data by containing both a reference to the location in memory where the data is stored, and a run time representation of the type of this data. Only local variables and parameters may be of the TypedReference type – fields cannot be typed references. The TypedReference type is not CLS-compliant.

 

There are a number of undocumented C# keywords (completely absent from the C# language specification) which we can use to create and manipulate variables of this type. We can create a typed reference from a variable using the __makeref keyword:

 

int i = 32;

TypedReference tr = __makeref(x);

 

The original type of the variable represented by the typed reference can be found using the
__reftype keyword:

 

Type t = __typeref(tr);

 

Finally, the value can be extracted from the TypedReference using the __refvalue keyword:

 

int j = __refvalue(tr, int);

 

Typed references can be used to represent method arguments in variable argument lists (varargs). Such argument lists can be passed into methods and accessed with the (similarly undocumented) __arglist keyword:

 

// Method with a variable argument list

// We use the __arglist keyword to represent this

public static void PrintToConsole(__arglist)

{

  // Create a System.ArgIterator object to loop through the args

  ArgIterator ai = new ArgIterator(__arglist);


 

  // Each item in the ArgIterator is a TypedReference,

  // and we can convert them to objects using the

  // TypedReference.ToObject() static method

 

  while (ai.GetRemainingCount() > 0)

  {

    TypedReference tr = ai.GetNextArg();

    Console.WriteLine(TypedReference.ToObject(tr));

  }

}

 

// Main method from which we call our varargs method

public static void Main()

{

  // Define some parameters with different types

  int x = 23;

  string y = "a string";

  double z = 19.25;

 

  // Call our variable argument method, passing

  // the arguments in, again using the __arglist keyword

  PrintToConsole(__arglist(x, y, z));

}

 

Note that, because this code uses undocumented keywords (which aren't guaranteed to work in future versions of C#), it isn't generally advisable to take this approach – for a cleaner way of doing this, see the section on the params keyword in Chapter 12.

DevASP.Net - Disclaimer - Privacy
© 2002-2010 DevASP.net