Understanding C# Data Types

Data Type and Type Conversion in C# .NET

In this article, I will explain about one of the main topics in C# - Data Types. You will also learn about the value and reference types, type conversions, and other features related to data types.

C# is a strongly typed language; therefore every variable and object must have a declared type.

Proper utilization of correct data types allows developers to make the most of the language

Data type in C#

There are two types of data type in C#.

Primitive (predefined) and Non-Primitive (User Defined)

  1. Primitive data types are further divided as
    • byte
    • short
    • int
    • float
    • double
    • long
    • char
    • bool
    • DateTime
    • string
    • object
  2. Non-primitive data types are further divided as
    • class
    • struct
    • enum
    • interface
    • delegate
    • array

Encoding Scheme To represent coding scheme.

ASCII                8 bits                         28     =      256
ANSI                 7 bits                         78     =      128
Unicode character sets  16 bits           216    =         65000

UTF (Unicode text file) can be.

  • UTF 7
  • UTF 8
  • UTF 16
  • UTF 32

Integer Type

C# supports eight predefined integer types.

Name CTS Type Description Range
sbyte System.SByte 8-bit signed integer -128 to 127 (-27 to 27-1)
short System.Int16 16-bit signed integer -32768 to 32767 (-215 to 215-1)
int System.Int32 32-bit signed integer -2147483648 to 2147483647 (-231 to 231-1)
long System.Int64 64-bit signed integer -9223372036854775808 to 9223372036854775807 (-263 to 263-1)
byte System.Byte 8-bit unsigned integer 0 to 255 (0 to 28-1)
ushort System.UInt16 16-bit unsigned integer 0 to 65535 (0 to 216-1)
uint System. UInt32 32-bit unsigned integer 0 to 4294967295 (0 to 232-1)
ulong System. UInt64 64-bit unsigned integer 0 to 18446744073709551615 (0 to 264-1)


Floating Point Type
 

Name CTS Type Description Significant Figures Range (approx.)
float System.Single 32-bit single precision floating point 7 plus & minus 1.5 X 10-45 to ±3.4 X 1038
double System.Double 32-bit single precision floating point 15/16 plus & minus 5.0 X 10-3245 to ±3.4 X 10308


Decimal Type
 

Name CTS Type Description Significant Figures Range (approx.)
decimal System.Decimal 128-bit high precision decimal notation 28 plus & minus 1.0 X 10-28 to ±7.9 X 1028


Boolean Type
 

Name CTS Type Values
bool System.Boolean true and false


Character Type
 

Name CTS Type Values
char System.Char Represents a single 16-bit (Unicode) character)


C# supports two predefined Reference Type
 

Name CTS Type Values
object System.Object The root type, from which all other types in the CTS derive (including value type)
string System.String Unicode character string

In .NET Microsoft has divided data types into two parts.

  1. Value Type (Fixed in size)
  2. Reference Type (Not fixed in size)

In the application context, value types are stored in the stack but reference types are stored in managed heap.

Value Type

  • Value types are fixed in size.
  • Value types are made in the system stack.
  • Actual values of data are stored in the stack.
  • If you assign a value of a variable to another it will create two copies.

All primitive data types except string and object are examples of value types.

The object is a supertype. It can store any type and any size of data. Object is called super type because it helps in inheritance.

struct and enum are value types.

Note. Stack is an operation entity (LIFO) i.e. it is fixed in size.

Reference Type

  • Reference types are not fixed in size.
  • They are maintained in a system-managed heap but it also uses a stack to store the reference of the heap.
  • Two primitive types (string and object) and non-primitive data types (class, interface & delegate) are examples of reference types.

CLR manages the heap (large memory area). The heap address is accessed from the stack. In reference type reference is used for processing using both managed heap and stack (operational entity).

Type Conversions

Conversion is based on type compatibility and data compatibility.

There are two types of conversions.

  1. Implicit Conversion
  2. Explicit Conversion

Implicit Conversion

In implicit conversion, the compiler will make the conversion for us without asking.

char -> int -> float is an example of data compatibility.

Compiler checks for type compatibility at compilation.

Practical demonstration of implicit conversion.

using System;

namespace implicit_conversion
{
    class Program
    {
        static void Main(string[] args)
        {
            int num1 = 20000;
            int num2 = 50000;
            long total;

            // In this the int values are implicitly converted to long data type;
            // you need not to tell compiler to do the conversion, it automatically does.
            total = num1 + num2;

            Console.WriteLine($"Total is: {total}");
            Console.ReadLine();
        }
    }
}

The below table shows the implicit type conversions that are supported by C#.

From To
sbyte short, int, long, float, double, decimal
byte short, ushort, int, uint, long, ulong, float, double, decimal
short int, long, float, double, decimal
ushort int, uint, long, ulong, float, double, decimal
int long, float, double, decimal
uint long, ulong, float, double, decimal
long float, double, decimal
ulong float, double, decimal
float double
char ushort, int, uint, long, ulong, float, double, decimal


Explicit Conversion

In explicit conversion, we specifically ask the compiler to convert the value into another data type.

CLR checks for data compatibility at runtime.

Explicit conversion is carried out using casts. When we cast one type to another, we deliberately force the compiler to make the transformation.

You should never expect that the cast would give you the best or correct result. Casts are potentially unsafe. Casting of big data type into small may lead to loosing of data.

Practical demonstration of explicit conversion.

using System;

namespace explicit_conversion
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 65;
            char alpha;
            alpha = (char)num;
            // In this the int values are explicitly converted to char data type;
            // you have to tell compiler to do the conversion, it uses casting.
            Console.WriteLine($"alphabet is: {alpha}");
            Console.ReadLine();
        }
    }
}

Note. You can also use Explicit Cast Operator () and unboxing for explicit conversion.

Microsoft .NET provides three ways of type conversion.

  1. Parsing
  2. Convert Class
  3. Explicit Cast Operator ()

Parsing

Parsing is used to convert string-type data to primitive value type. For this, we use parse methods with value types.

Practical demonstration of parsing.

using System;

namespace parsing
{
    class Program
    {
        static void Main(string[] args)
        {
            //using parsing
            int number;
            float weight;
            Console.Write("Enter any number: ");
            number = int.Parse(Console.ReadLine());
            Console.Write("Enter your weight: ");
            weight = float.Parse(Console.ReadLine());
            Console.WriteLine($"You have entered: {number}");
            Console.WriteLine($"You weight is: {weight}");
            Console.ReadLine();
        }
    }
}

Convert Class

One primitive type to another primitive type.

This class contains different static methods like ToInt32(), ToInt16(), ToString(), DateTime (), etc used in type conversion.

Practical demonstration of Convert class.

using System;

namespace convert_conversion
{
    class Program
    {
        static void Main(string[] args)
        {
            // example of using convert class
            string num = "23";
            int number = Convert.ToInt32(num);
            int age = 24;
            string vote = Convert.ToString(age);
            Console.WriteLine($"Your number is : {number}");
            Console.WriteLine($"Your voting age is : {age}");
            Console.ReadLine();
        }
    }
}

Explicit Cast Operator ()

In general, this operator is used with non-primitive types for up-level or down-level casting. But it can also used with any type having type compatibility and data type compatibility.

using System;

namespace explicit_cast_conversion
{
    class Program
    {
        static void Main(string[] args)
        {
            int num1, num2;
            float avg;
            num1 = 10;
            num2 = 21;
            avg = (float)(num1 + num2) / 2;
            Console.WriteLine($"average is: {avg}");
            Console.ReadLine();
        }
    }
}

Boxing and unboxing

Boxing and unboxing an important concepts in C# type systems. With Boxing and unboxing, one can link between value types and reference types by allowing any value of a value type to be converted to and from a type object.

Boxing

  • Boxing is a mechanism in which value type is converted into reference type.
  • It is an implicit conversion process in which object type (supertype) is used.
  • In this process type and value both are stored in the object type.

Unboxing

  • Unboxing is a mechanism in which reference type is converted into value.
  • It is an explicit conversion process.

Program to show boxing and unboxing.

using System;

namespace boxing
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = 10;
            object o = i;               // boxing
            int j = (int)o;             // unboxing
            Console.WriteLine("value of o object : " + o);
            Console.WriteLine("Value of j : " + j);
            Console.ReadLine();
        }
    }
}

Hope you have some idea about data types, value types and reference types, and boxing and unboxing. Your feedback and constructive contributions are welcome. Please feel free to contact me for feedback or comments you may have about this article.


Similar Articles