Author : HASSAN MD TAREQ | Updated : 2021/03/22

Declaring variable

// Declaring variable
int x = 0;
float y = 0.0F;
bool t = false;
decimal d = 0.0M;


// Type Inference
var x = 10;               // int
var x = true;             // bool
var x = "Hassan";    	  // string


// Implicitly typed variables must be initialized with proper value
var str = null             // invalid, compiler can't figure out type of str
var str = (string) null;   // compiler can infer type of str as string, and assigned value is null

Primitive Types

Every programming language has its own set of basic, built-in data types using which and object oriented approach we can build more complex data types such as classes & structures. C# has its own set of basic, fundamental types. Basic built-in types in C# are stored under System namespace, they are called primitive types.

Since primitive types are used quite often, C# has a simplified way to create them. Instead of writing code like this: System.Double x = new System.Double(); to a simpler way like this: double x = 0;

All primitive types can be conditionally divided to the following types:

</details>

C# Data Types Table

C Sharp Data Types Table

Everything is Object

For each primitive data type, there is a wrapper class that represents it as an object. For example, System.Int32 class wraps the int data type, and System.Double class wraps the double data type.

int x = 0
int x = new int()                     // same as int x = 0
System.Int32 x = new System.Int32();  // same as int x = 0

All primitive types besides string are derived from System.ValueType class which in its turn is derived from System.Object. It means we can call methods of System.Object on any primitive type and all primitive types are derived from System.Object that fits .NET methodology. For example, calling GetType, you may always get FCL type that corresponds to short name. Also, can typeof operator be used for getting type of the variable. Children of ValueType are automatically stored in stack when we declare them. Basing on it, they are very fast and effective.

Boxing and unboxing

The process of converting a value type to a reference type is called boxing. The inverse process - converting a reference type to a value type, is called unboxing.

int i = 123;      // i is value type 
object o = i;     // boxing 
int j = (int)o;   // unboxing

In relation to simple assignments, boxing and unboxing are computationally expensive processes. When a value type is boxed, a new object must be allocated and constructed. To a lesser degree, the cast required for unboxing is also expensive computationally.

Default Value

One of the benefits of OOP is value type variables are initialized (when created) by default constructor (since everything is 0bject, there is constructor). The following table shows the default values of value types returned by the default constructors. Default constructors are invoked by using the new operator, as follows:

int x = new int();

The above statement is the same as: int x = 0;

C Sharp Default Value Table

C Sharp Default Value Table

Type Suffix

// Type Suffix
decial m = 0M;
double d = 0.0D;
float f = 0.0F;
long l = 0L;
uint uin = 0U;
ulong ul = 0UL;

Type Suffix Table

C Sharp Type Suffix Table