In this article, we would be learning about data types, typecasting in C#.
Data Types
A data type is an entity which specifies what type of value a variable has, and what kind of operations can be applied to the variable.
In simpler terms, a data type defines the type and size of a variable value.
There are 2 major data type classifications in C#.
- Value Types – A variable of a value type contains an instance of the type.
- Reference Types – A variable of a reference type contains a reference to the instance of the type.
Value and Reference Types are further branched into their own sub classifications.
Value Types further get categorized into:
- Basic/Simple Types
- Enums
- Structs
- Nullables
Reference Types are further categorized into:
- Classes
- Interfaces
- Arrays
- Delegates
Below is a pictorial representation:
The below table gives us an idea about the range of few predefined types.
| C# Type | Description | Range | Suffix |
| byte | 8-bit unsigned integer | 0 to 255 | |
| sbyte | 8-bit signed integer | -128 to 127 | |
| short | 16-bit signed integer | -32,768 to 32,767 | |
| ushort | 16-bit unsigned integer | 0 to 65,535 | |
| int | 32-bit signed integer | -2,147,483,648 to 2,147,483,647 | |
| uint | 32-bit unsigned integer | 0 to 4,294,967,295 | u |
| long | 64-bit signed integer | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | l |
| ulong | 64-bit unsigned integer | 0 to 18,446,744,073,709,551,615 | ul |
| float | 32-bit single-precision floating point type | -3.402823e38 to 3.402823e38 | f |
| double | 64-bit double-precision floating point type | -1.79769313486232e308 to 1.79769313486232e308 | d |
| decimal | 128-bit decimal type | (+ or -)1.0 x 10e-28 to 7.9 x 10e28 | m |
| char | 16-bit single Unicode character | Any valid character, e.g. a,*, \x0058 (hex), or\u0058 (Unicode) | |
| bool | 8-bit logical true/false value | True or False | |
| object | Base type of all other types. | ||
| string | A collection of Unicode characters | ||
| DateTime | Represents date & time | 0:00:00 1/1/0001 to 11:59:59 12/31/9999 |
Let’s see few data types in action via code.
//We have assigned defaults to few pre-defined vaue types.
//We are evaluating the type, min value and max value programmatically
byte byteVar = default;
sbyte sbyteVar = default;
short shortVar = default;
ushort ushortVar = default;
int intVar = default;
uint uintVar = default;
long longVar = default;
ulong ulongVar = default;
float floatVar = default;
double doubleVar = default;
decimal decimalVar = default;
bool boolVar = default;
DateTime dateTimeVar = default;
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(byte), byteVar, byte.MinValue, byte.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(sbyte), sbyteVar, sbyte.MinValue, sbyte.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(short), shortVar, short.MinValue, short.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(ushort), ushortVar, ushort.MinValue, ushort.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(int), intVar, int.MinValue, int.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(uint), uintVar, uint.MinValue, uint.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(long), longVar, long.MinValue, long.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(ulong), ulongVar, ulong.MinValue, ulong.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(float), floatVar, float.MinValue, float.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(double), doubleVar, double.MinValue, double.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(decimal), decimalVar, decimal.MinValue, decimal.MaxValue);
Console.WriteLine("Type: {0}, Default Value: {1}", typeof(bool), boolVar);
Console.WriteLine("Type: {0}, Default Value: {1}, MinValue: {2}, MaxValue: {3}", typeof(DateTime), dateTimeVar, DateTime.MinValue, DateTime.MaxValue);
Output:
Type: System.Byte, Default Value: 0, MinValue: 0, MaxValue: 255
Type: System.SByte, Default Value: 0, MinValue: -128, MaxValue: 127
Type: System.Int16, Default Value: 0, MinValue: -32768, MaxValue: 32767
Type: System.UInt16, Default Value: 0, MinValue: 0, MaxValue: 65535
Type: System.Int32, Default Value: 0, MinValue: -2147483648, MaxValue: 2147483647
Type: System.UInt32, Default Value: 0, MinValue: 0, MaxValue: 4294967295
Type: System.Int64, Default Value: 0, MinValue: -9223372036854775808, MaxValue: 9223372036854775807
Type: System.UInt64, Default Value: 0, MinValue: 0, MaxValue: 18446744073709551615
Type: System.Single, Default Value: 0, MinValue: -3.4028235E+38, MaxValue: 3.4028235E+38
Type: System.Double, Default Value: 0, MinValue: -1.7976931348623157E+308, MaxValue: 1.7976931348623157E+308
Type: System.Decimal, Default Value: 0, MinValue: -79228162514264337593543950335, MaxValue: 79228162514264337593543950335
Type: System.Boolean, Default Value: False
Type: System.DateTime, Default Value: 01-01-0001 00:00:00, MinValue: 01-01-0001 00:00:00, MaxValue: 31-12-9999 23:59:59
type.MinValue, type.MaxValue come in very handy, when we need to confirm for the range of a given data type.
Let’s discuss in brief about string type, which is actually a reference type.
- string is nothing but a collection of characters, anything enclosed within double quotes constitutes a string.
- The default value of string is NULL.
- string derives from the System.String class.
//string data type
string message = default;
Console.WriteLine("Type: {0}, Default: {1}", typeof(string), message);
Output:
Type: System.String, Default:
NULL being the default value of string, when output to the console does not print anything, i.e. empty.
We would discuss Classes, Interfaces, Delegates etc. in great detail in the future articles.
TypeCasting
Typecasting is when we convert from one data type to another, either implicitly or explicitly.
- Ex1: Explicit conversion from int to string
//type conversion
int aBigNumber = 23145677;
string aBigNumberInStringFormat = Convert.ToString(aBigNumber);
Console.WriteLine(aBigNumberInStringFormat);
The above is an example of explicit conversion, in which we need to specify to which type the conversion needs to happen.
Explicit conversion can be carried out via 2 ways.
- Convert method
- Direct invocation of the desired destination type within parentheses
//2 types of explicit conversion
int aBigNumber = 23145677;
string aBigNumberInStringFormat = Convert.ToString(aBigNumber); // Convert method
uint typeCastedNumber = (uint)aBigNumber; // Direct invocation of destination type
Console.WriteLine(aBigNumberInStringFormat);
Console.WriteLine(typeCastedNumber);
- Ex2: Implicit conversion from int to long
//Implicit type conversion
int againANumber = 99998;
long longNumber = againANumber;
Console.WriteLine(longNumber);
The below table denotes what all types support implicit type conversion.
| Implicit Type Conversion | |
| Source Type | Destination Type |
| sbyte | short, int, long, float, double, decimal |
| byte | short, ushort, int, uint, long, ulong, float, double, decimal |
| short | int, long, float, double, or decimal |
| ushort | int, uint, long, ulong, float, double, or decimal |
| int | long, float, double, or decimal. |
| uint | long, ulong, float, double, or decimal |
| long | float, double, or decimal |
| ulong | float, double, or decimal |
| char | ushort, int, uint, long, ulong, float, double, or decimal |
| float | double |
Variables – Revisited
In one of the earlier articles, we learnt about variables.
Let us revisit them again now that we have a good knowledge of data types.
We can create variables with access modifiers and few other keywords as well.
The base structure type variableName = value; remains the same though.
[private|public|internal|protected] [static|const|readonly] type variableName=value;
The first set (blue text) includes access modifiers :
- private
- public
- internal
- protected
while the second set (red text) includes a few extra keywords :
- static
- const
- readonly
The first set denotes the accessibility level of the variable, while the second set denotes whether the variable has to be static, const or readonly.
These keywords are quite important and are used widely in programming, depending upon scenarios and use cases.
