Working with System Data Types and Corresponding C# Keywords
C# defines keywords for fundamental data types, which are used to represent local variables, class data member variables, method return values, and parameters.
Rather, C# data type keywords are actually shorthand notations for full-blown types in the System namespace.
The Intrinsic Data Types of C#
| C# Shorthand | CLS Complaint | System Type | Meaning in Life |
| bool | yes | Boolean | Represents truth or falsity |
| sbyte | no | Sbyte | Signed 8-bit number |
| byte | yes | Byte | Unsigned 8-bit number |
| short | yes | Int16 | Signed 16-bit number |
| ushort | No | UInt16 | Unsigned 16-bit number |
| int | yes | Int32 | Signed 32-bit number |
| uint | no | UInt32 | Unsigned 32-bit number |
| long | yes | Int64 | Signed 64-bit number |
| ulong | no | UInt64 | Unsigned 64-bit number |
| char | yes | Char | Single 16-bit Unicode character |
| float | yes | Single | 32-bit floating point number |
| double | yes | Double | 64-bit floating point number |
| decimal | yes | Decimal | 128-bit floating point number |
| string | yes | String | Represents a set of Unicode characters. |
| object | yes | Object | The base class of all types in the .NET universe. |
CLS-compliant .NET Core code can be used by any other .NET programming language. If you expose non-CLS-complaint data from your programs, other .NET languages may not be able to make use of it.
Understanding Variable Declaration and Initialization
When you are declaring a local variable, you do so by specifying the data types, followed by the variable name.
// Local variables are declared as so:
// dataType varName;
int myInt;
string myString;
Be aware that it is a "compiler error" to make use of a local variable before assigning an initial value.
It is good to practice to assign an initial value to your local data points at the time of declaration.
// Local variables are declared and initialized as follows:
// dataType varName = initialValue;
int myInt = 10;
// You can also declare and assign on 2 lines.
string myString;
myString = "This is my character data";
The default Literal (New 7.1)
The "default" literal assigns a variable the default value for its data types. This works for standard data types as well as custom classes and generic types.
int myInt = default;
Using Intrinsic Data Types and the new Operator (Updated 9.0)
All intrinsic data types support what is known as a default constructor. This feature allows you to create a variable using the "new" keyword which automatically sets the variable to its default value.
- bool variables are set to false.
- Numeric data is set to 0 (or 0.0 for floating-point data types)
- char variables are set to a single empty character.
- BigInteger variables are set to 0.
- DateTime variables are set to 1/1/0001 12:00:00 AM.
- Object references (including strings) are set to null.
bool b = new bool();
int i = new int();
double d = new double();
DateTime dt = new DateTime();
C# 9.0 added a shortcut for creating variable instances. This shortcut is simply using the keyword new() without the data type.
bool b = new();
int i = new();
double d = new();
DateTime dt = new();
Understanding the Data Type Class Hierarchy
- Each type ultimately derives from System.Object
- Many numerical data types derive from a class named System.ValueType. Descendants of ValueType are automatically allocated on the Stack and, therefore, have a predictable lifetime and are quite efficient. On the other hand, types that do not have System.ValueType in their inheritance chain (such as System.Type, System.String, System.Array, System.Exception, and System.Delegate) are not allocated on the stack but on the garbage-collected heap.
Console.WriteLine(12.GetHashCode());// 12
Console.WriteLine(12.Equals(25)); // False
Console.WriteLine(12.ToString()); // 12
Console.WriteLine(12.GetType()); // System.Int32 Understanding the Members of Numerical Data Types
The numerical data types of .NET Core support MaxValue and MinValue properties that provide information regarding the range a given type can store.
Console.WriteLine("Max of int {0}", int.MaxValue);
Console.WriteLine("Min of int {0}", int.MinValue);
When you define a literal whole number (such as 500), the runtime will default the data type to "int".
Likewise, literal floating-point data (such as 55.333) will default to a "double".
To set the underlying data type to a long use suffix "l" or "L" (4L).
To declare a float variable, use the suffix "f" or "F" to the raw numerical value (5.3F).
Use the suffix "m" or "M" to a floating-point number to declare a decimal (300.5M).
Understanding the Members of System.Boolean
System.Boolean data type, only valid assignment a C# bool can take is from the set {true | false}.
No -> MinValue & MaxValue rather
Yes -> TrueString & FalseString (yields "True" or "False" string, respectively).
Console.WriteLine(bool.FalseString);
Console.WriteLine(bool.TrueString);Understanding the Members of System.Char
System.Char type provides you with a great deal of functionality beyond the ability to hold a single point of character data.
Methods
IsDigit, IsLetter, IsWhiteSpace, IsPunctuation
Parsing Values from String Data
The .NET data types provide the ability to generate a variable of their underlying type given a textual equivalent.
bool b = bool.Parse("true");
double d = double.Parse("99.44");
int i = int.Parse("4");
char c = char.Parse("k");Using TryParse to Parse Value from String Data
One issue with the preceding codes is that an exception will be thrown if the string cannot be cleanly converted to the correct data type.
// Without TryParse
bool b = bool.Parse("Hello"); The TryParse() statement takes an "out" parameter and returns a bool if the parsing was successful.
// Using TryParse
if (bool.TryParse("True", out bool b)){
Console.WriteLine($"B is successfully converted to a bool : {b}")
}
Using System.DateTime and System.TimeSpan
The DateTime type contains data that represents a specific date (month, day, year) and time value, both of which may be formatted in a variety of ways using the supplied members. The TimeSpan structure allows you to easily define and transform units of time using various members.
DateTime dt = new DateTime(2015, 10, 17); // (year, month, day)
Console.WriteLine("Day {0} {1}", dt.Date, dt.DayOfWeek);
dt = dt.AddMonths(2);
TimeSpan ts = new TimeSpan(4, 30, 0); // (hours, minutes, seconds)
Console.WriteLine(ts);
The DateOnly and TimeOnly structs were added in .NET 6/C# 10 , and each represents half of the DateTime type. The DateOnly struct aligns with the SQL Server Date type, and the TimeOnly struct aligns with the SQL Server Time Type.
DateOnly d = new DateOnly(2021, 07, 21);
TimeOnly t = new TimeOnly(13, 30, 0, 0);
Working with the System.Numerics Namespace
The System.Numerics namespace defines a structure named "BigInteger". The BigInteger data type can be used when you need to represent humongous numerical values, which are not constrained by a fixed upper or lower limit.
Also System.Numerics namespace defines "Complex", which allows you to model mathematically complex numerical data.
using System.Numerics; Note : After you assign a value to a BigInteger, you cannot change it, as the data is immutable.
BigInteger big = new BigInteger("999");
Properties
| IsEven | The big integer is an even or not number. |
| IsPowerOfTwo | Indicates whether the value of the current BigInteger object is a power of 2. |
Using Digit Separators (New 7.0)
C# 7.0 introduced the underscore (_) as a digit separator (for integer, long, decimal, double, or hex types.)
Console.WriteLine(123_456);
Console.WriteLine(123_456_12F);
Console.WriteLine(123_456.12M);
Console.WriteLine(0x_00_00F);
Using Binary Literals
Starts -> 0b_
Console.WriteLine("16 : {0}", 0b_0001_0000);
Console.WriteLine("32 : {0}", 0b_0010_0000);