4.2. More On Data Types¶
4.2.1. Static vs. Dynamic Typing¶
In a dynamically typed programming language (like JavaScript or Python), a variable can refer to a value of any data type (string, number, object, etc.) at any time. When the variable is used, the interpreter figures out what type it is and behaves accordingly.
C# is a statically typed language. When a variable is declared in a statically typed language, the data type for the value must be specified. Once the declaration is made, the variable cannot refer to a value of any other type.
For example, this is legal in JavaScript, a dynamically typed language:
Example
1 2 3 4 | let dynamicVariable = "dog";
console.log(typeof(dynamicVariable));
dynamicVariable = 42;
console.log(typeof(dynamicVariable));
|
Output
string
number
After line 1 executes, dynamicVariable
holds a string
data type. After
line 3 runs, dynamicVariable
is reassigned to a number
type. dynamicVariable
is allowed to hold values of different types, which can be reassigned as
needed when the program runs. The keyword typeof
is used in lines 2 and 4
to verify the data type.
However, the corresponding code in C# will result in a build error:
Example
1 2 | string staticVariable = "dog";
staticVariable = 42;
|
Output
Error CS0029: Cannot implicitly convert type 'int' to 'string'
The compiler error occurs when we try to assign 42
to a variable of type
string
.
Take-home lesson: We must declare the type of every variable in
a statically typed language. This is done by declaring the data type for the
variable or parameter BEFORE its name, as we did in the example above:
string staticVariable = "dog"
.
Note
We only need to specify the type of a variable when declaring it. Further use of the variable does not require us to identify its type. Doing so will result in an error.
Dynamic and static typing are examples of different type systems. The type system of a programming language is one of the most important high-level characteristics that programmers use when discussing the differences between languages. Here are a few examples of popular languages falling into these two categories:
Dynamic: Python, Ruby, JavaScript, PHP
Static: C#, C, C++, Java, TypeScript
Because we need to give plenty of attention to types when writing C# code, let’s begin by exploring the most common data types in this language.
4.2.2. Built-In Types¶
In C#, all of the basic data types are objects — we’ll get into this idea shortly. Though the so-called built-in data types also have short names that differ from typical class name conventions.
We provide here a list of some of the most common types, along with the official .NET class name. The .NET gives us a class library with object types, which we will learn about later. We’ll generally prefer to use the short names for each of these.
Short name |
.NET Class |
Examples |
Notes |
---|---|---|---|
|
|
-5, 1024 |
|
|
|
3.14159, 2.0 |
Doubles are twice as precise and can use decimals. |
|
|
‘a’, ‘!’ |
A single Unicode character. Must be enclosed in single quotes |
|
|
|
|
|
|
|
Reference value. Non-Primitive Type. Must be enclosed in double quotes |
Not all built-in data types in C# are listed here, only the most commonly used types that beginners are likely to encounter. If you’re curious, read more about built-in types in C#.
Note
Having distinctions between integers and doubles can help with code design. For example, an inventory-tracking program stores items and the number of each number in stock. Since a store cannot have 3.5 shirts in stock, the programmer makes the quantity of each item integer values as opposed to doubles.
4.2.2.1. Primitive Types¶
The types in the table above are known as primitive types. A primitive data type is a basic building block of a programming language. Using primitive data types, we can build more complex data structures.
4.2.2.2. Non-primitive Types¶
Primitive data types are immutable and can be combined to build larger data
structures. One example is forming the string
“LaunchCode” from multiple
char
characters ('L'
, 'a'
, 'u'
, etc.).
string
is another built-in type in C# and it is also a non-primitive data type. We’ll delve into
how strings work in C# in a future chapter.
4.2.3. Reference and Value Types¶
We can group types in C# into two categories: value types and
reference types. Variables holding value types directly contain
their data, and include numeric types (int
, double
, etc.),
bool
, and a handful of others that we won’t encounter in this
course. The primitive, built-in types we list above are all value types.
Whereas reference types stores the address where the value is being stored.
Another way to think about this is that a reference type points to the
memory location that stores the data.
4.2.3.1. Boxing¶
As we mention above, all types in C# are treated as objects. Even value types. This can be accomplished through processes called boxing and unboxing. Converting from a value type to a reference type is called boxing, and the reverse process (reference to value) is called unboxing. C# is known as a unified type system because it implicitly boxes values types to be treated as objects.
int i = 123; // This is a value type.
object o = i; // Boxing the value type into a reference type.
int j = (int)o; // Unboxing the reference type back into a value type.
4.2.4. Check Your Understanding¶
Question
Which of the following is NOT a number data type in C#:
number
int
float
double
Question
Which of the following terms refers to C#’s behavior of treating all types as objects:
static type system
dynamic type system
reference type system
unified type system