Книга: C# 2008 Programmer
Value Types
Разделы на этой странице:
Value Types
A value type variable contains the data that it is assigned. For example, when you declare an int (integer) variable and assign a value to it, the variable directly contains that value. And when you assign a value type variable to another, you make a copy of it. The following example makes this clear:
class Program {
static void Main(string[] args) {
int num1, num2;
num1 = 5;
num2 = num1;
Console.WriteLine("num1 is {0}. num2 is {1}", num1, num2);
num2 = 3;
Console.WriteLine("num1 is {0}. num2 is {1}", num1, num2);
Console.ReadLine();
return;
}
}
The output of this program is:
num1 is 5. num2 is 5
num1 is 5. num2 is 3
As you can observe, num2
is initially assigned a value of num1
(which is 5). When num2
is later modified to become 3, the value of num1
remains unchanged (it is still 5). This proves that the num1
and num2
each contains a copy of its own value.
Following is another example of value type. Point is a structure that represents an ordered pair of integer x and y coordinates that defines a point in a two-dimensional plane (structure is another example of value types). The Point
class is found in the System.Drawing
namespace and hence to test the following statements you need to import the System.Drawing
namespace.
Chapter 4 discusses structures in more detail.
Point pointA, pointB;
pointA = new Point(3, 4);
pointB = pointA;
Console.WriteLine("point A is {0}. pointB is {1}",
pointA.ToString(), pointB.ToString());
pointB.X = 5;
pointB.Y = 6;
Console.WriteLine("point A is {0}. pointB is {1}",
pointA.ToString(), pointB.ToString());
These statements yield the following output:
point A is {X=3,Y=4}. pointB is {X=3,Y=4}
point A is {X=3,Y=4}. pointB is {X=5,Y=6}
As in the earlier example, changing the value of the pointB does not change the value of pointA.
Predefined Value Types
The .NET Framework ships with a set of predefined C# and .NET value types. These are described in the following table.
C# Type | .NET Framework Type | Bits | Range |
---|---|---|---|
bool |
System.Boolean |
True or false | |
byte |
System.Byte |
8 | Unsigned 8-bit integer values from 0 to 255 |
sbyte |
System.SByte |
8 | Signed 8-bit integer values from -128 to 127 |
char |
System.Char |
16 | 16-bit Unicode character from U+0000 to U+ffff |
decimal |
System.Decimal |
128 | Signed 128-bit number from ±1.0?10-28 to ±7.9?1028 |
double |
System.Double |
64 | Signed 64-bit floating point number; approximately from ±5.0?10-324 to ±1.7?10308 |
float |
System.Single |
32 | Signed 32-bit floating point number; approximately from ±1.5?10-45 to ±3.4?1038 |
int |
System.Int32 |
32 | Signed 32-bit integer number from -2,147,483,648 to 2,147,483,647 |
uint |
System.UInt32 |
32 | Unsigned 32-bit integer number from 0 to 4,294,967,295 |
long |
System.Int64 |
64 | Signed 64-bit integer number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
ulong |
System.UInt64 |
64 | Unsigned 64-bit integer number from 0 to 18,446,744,073,709,551,615 |
short |
System.Int16 |
16 | Signed 16-bit integer number from -32,768 to 32,767 |
ushort |
System.UInt16 |
16 | Unsigned 16-bit integer number from 0 to 65,535 |
To declare a variable of a predefined type, you can either use the C# type or the .NET Framework type. For example, to declare an integer variable, you can either use the int or System.Int32
type, as shown here:
int num1 = 5;
//---or---
System.Int32 num2 = 5;
To get the type of a variable, use the GetType()
method:
Console.WriteLine(num1.GetType()); //---System.Int32---
To get the .NET equivalent of a C# type, use the typeof()
method. For example, to learn the .NET type equivalent of C#'s float type, you can use the following statements:
Type t = typeof(float);
Console.WriteLine(t.ToString()); //---System.Single---
To get the size of a type, use the sizeof()
method:
Console.WriteLine("{0} bytes", sizeof(int)); //---4 bytes---
In C#, all noninteger numbers are always treated as a double. And so if you want to assign a noninteger number like 3.99 to a float
variable, you need to append it with the F
(or f
) suffix, like this:
float price = 3.99F;
If you don't do this, the compiler will issue an error message: "Literal of type double cannot be implicitly converted to type 'float'; use an 'F' suffix to create a literal of this type."
Likewise, to assign a noninteger number to a decimal variable, you need to use the M suffix:
decimal d = 4.56M; //---suffix M to convert to decimal---
float f = 1.23F; //---suffix F to convert to float---
You can also assign integer values using hexadecimal representation. Simply prefix the hexadecimal number with 0x
, like this:
int num1 = 0xA;
Console.WriteLine(num1); //---10---
Nullable Type
All value types in C# have a default value when they are declared. For example, the following declaration declares a Boolean and an int
variable:
Boolean married; //---default value is false---
int age; //--- default value is 0---
To learn the default value of a value type, use the default
keyword, like this:
object x; x = default(int);
Console.WriteLine(x); //---0---
x = default(bool);
Console.WriteLine(x); //---false---
However, C# forbids you from using a variable if you do not explicitly initialize it. The following statements, for instance, cause the compiler to complain:
Boolean married;
//---error: Use of unassigned local variable 'married'---
Console.WriteLine(married);
To use the variable, you first need to initialize it with a value:
Boolean married = false;
Console.WriteLine(married); //---now OK---
Now married
has a default value of false
. There are times, though, when you do not know the marital status of a person, and the variable should be neither true
nor false
. In C#, you can declare value types to be nullable, meaning that they do not yet have a value.
To make the married
variable nullable, the above declaration can be rewritten in two different ways (all are equivalent):
Boolean? married = null;
//---or---
Nullable<Boolean> married = null;
The syntax T?
(example, Boolean?
) is shorthand for Nullable<T>
(example, Nullable<Boolean>
), where T is a type.
You read this statement as "Nullable of Boolean." The <> represents a generic type and will be discussed in more detail in Chapter 9.
In this case, married can take one of the three values: true
, false
, or null
.
The following code snippet prints out "Not Married":
Boolean? married = null;
if (married == true)
Console.WriteLine("Married");
else
Console.WriteLine("Not Married"); //---this will be printed---
That's because the if
statement evaluates to false
(married is currently null), so the else
block executes. A much better way to check would be to use the following snippet:
if (married == true)
Console.WriteLine("Married");
else if (married==false)
Console.WriteLine("Not Married");
else
Console.WriteLine("Not Sure"); //---this will be printed---
Once a nullable type variable is set to a value, you can set it back to nothing by using null
, as the following example shows:
married = true; //---set it to True---
married = null; //---reset it back to nothing---
To check the value of a nullable variable, use the HasValue
property, like this:
if (married.HasValue) {
//---this line will be executed only
// if married is either true or false---
Console.WriteLine(married.Value);
}
You can also use the == operator to test against null, like the following:
if (married == null) {
//---causes a runtime error---
Console.WriteLine(married.Value);
}
But this results in an error because attempting to print out the value of a null variable using the Value
property causes an exception to be thrown. Hence, always use the HasValue
property to check a nullable variable before attempting to print its value.
When dealing with nullable types, you may want to assign a nullable variable to another variable, like this:
int? num1 = null;
int num2 = num1;
In this case, the compiler will complain because num1
is a nullable type while num2
is not (by default, num2
cannot take on a null value unless it is declared nullable). To resolve this, you can use the null coalescing operator (??
). Consider the following example:
int? num1 = null;
int num2 = num1 ?? 0;
Console.WriteLine(num2); //---0---
In this statement, if num1
is null
, 0 will be assigned to num2
. If num1
is not null
, the value of num1
will be assigned to num2
, as evident in the following few statements:
num1 = 5;
num2 = num1 ?? 0;
Console.WriteLine(num2); //---5---