Please enable Javascript to correctly display the contents on Dot Net Tricks!
C# Questions & Answers

Data Type

  1. What is Data Type?

    Data Type refers to the type of data that can be stored in a variable. It also specifies how much memory would be allocated to a variable and the operations that can be performed on that variable.

    C# is rich in data type which is broadly divided into two categories.

    1. Value Type

    2. Reference Type

  2. What is value type and reference type?

    Value Type

    A value type variable store actual values. Also, value types are stored in a stack. Values types are of two types - built-in and user-defined. Value types are derived from System.ValueType.

    Reference Type

    A reference type variable stores a reference to the actual value. It means reference type contains a pointer to another memory location that holds the actual data. Also, reference types are stored in a heap. Reference types are of two types - built-in and user-defined. Reference types are derived from System.Object.

  3. What is dynamic type?

    Dynamic type was introduced with C# 4.0. Dynamic types are declared with the dynamic keyword. Dynamic types bypass compile-time type checking and these operations are resolved at run time. During compilation, dynamic is converted to System.Object and compiler will emit the code for type safety during runtime.

    If the value provided to a dynamic variable is not valid, exception would be thrown at run time not at compile time.

    class Program
    {
     public static void Main()
     {
     dynamic d = 1; //assigning integer
     Console.WriteLine(d);
     d = "Hi Dynamic"; //assigning string to the same variable d
     Console.WriteLine(d);
     d = TestData(); //assigning method result to the same variable d
     Console.WriteLine(d);
     // You can call anything on a dynamic variable,
     // but it may result in a runtime error
     Console.WriteLine(d.Error);
     }
     public static double TestData()
     {
     return 12.80;
     }
    }
    /* Out Put
     10
     Hi Dynamic
     12.80
     RuntimeBinderException was unhandled, 'double' does not contain a definition for 'Error'
    */
    
  4. What is Nullable Type?

    Value types (like int, bool etc.) which accept either their normal values or a null value are referred as Nullable types. Nullable types are instances of the Nullable struct.

    For example, A Nullable<bool> is pronounced as "Nullable of bool," and it can accept the values true, false or null.

    Nullable types can also be defined using ? type modifier. This token is placed immediately after the value type being defined as nullable.

    //assigning normal value
    Nullable flag = true;
    //OR
    bool? flag = true;
    //assigning normal value
    Nullable x = 20;
    //OR
    int? x = 20;
    
  5. When to use Nullable Type?

    When you deal with databases and other data types which contain elements or variables that may or not be assigned a value i.e. undefined, nullable types are used to store the values of such elements or variables.

  6. Can you define string as Nullable Type?

    You can’t declare a string as nullable because, it is implicitly nullable. Hence, declaring a string variable like string? strName results a compile time error.

  7. What is the difference between int, Int16, Int32 and Int64?

    In the learning phase developer are not much aware of the difference between primitive, FCL (framework class library), reference, and value types. This cause bugs and performance issues into the code. In this article, I would like to expose the different behavior of integer type.

    int

    1. It is a primitive data type defined in C#.

    2. It is mapped to Int32 of FCL type.

    3. It is a value type and represent System.Int32 struct.

    4. It is signed and takes 32 bits.

    5. It has minimum -2147483648 and maximum +2147483647 capacity.

    Int16

    1. It is a FCL type.

    2. In C#, short is mapped to Int16.

    3. It is a value type and represent System.Int16 struct.

    4. It is signed and takes 16 bits.

    5. It has minimum -32768 and maximum +32767 capacity.

    Int32

    1. It is a FCL type.

    2. In C#, int is mapped to Int32.

    3. It is a value type and represent System.Int32 struct.

    4. It is signed and takes 32 bits.

    5. It has minimum -2147483648 and maximum +2147483647 capacity.

    Int64

    1. It is a FCL type.

    2. In C#, long is mapped to Int64.

    3. It is a value type and represent System.Int64 struct.

    4. It is signed and takes 64 bits.

    5. It has minimum –9,223,372,036,854,775,808 and maximum 9,223,372,036,854,775,807 capacity.

    Note

    1. A number of developers think that int represents a 32-bit integer when the application is running on a 32-bit OS and it represents a 64-bit integer when the application is running on a 64-bit OS. This is absolutely wrong.

    2. In C# int is a primitive data type and it always mapped to System.Int32 whether the OS is 32-bit or 64-bit.

  8. What is the difference between constant, readonly and static?

    Constant

    Constant fields or local variables must be assigned a value at the time of declaration and after that they cannot be modified. By default constant are static, hence you cannot define a constant type as static.

    public const int X = 10;
    

    A const field is a compile-time constant. A constant field or local variable can be initialized with a constant expression which must be fully evaluated at compile time.

    void Calculate(int Z)
    {
     const int X = 10, X1 = 50;
     const int Y = X + X1; //no error, since its evaluated a compile time
     const int Y1 = X + Z; //gives error, since its evaluated at run time
    }
    

    You can apply const keyword to built-in value types (byte, short, int, long, char, float, double, decimal, bool), enum, a string literal, or a reference type which can be assigned with a value null.

    const MyClass obj1 = null;//no error, since its evaluated a compile time
    const MyClass obj2 = new MyClass();//gives error, since its evaluated at run time
    

    Constants can be marked as public, private, protected, internal, or protected internal access modifiers.

    Use the const modifier when you sure that the value a field or local variable would not be changed.

    ReadOnly

    A readonly field can be initialized either at the time of declaration or with in the constructor of same class. Therefore, readonly fields can be used for run-time constants.

    class MyClass
    {
     readonly int X = 10; // initialized at the time of declaration
     readonly int X1;
     public MyClass(int x1)
     {
     X1 = x1; // initialized at run time
     }
    }
    

    Explicitly, you can specify a readonly field as static since, like constant by default it is not static. Readonly keyword can be apply to value type and reference type (which initialized by using the new keyword) both. Also, delegate and event could not be readonly.

    Use the readonly modifier when you want to make a field constant at run time.

    Static

    The static keyword is used to specify a static member, which means static members are common to all the objects and they do not tied to a specific object. This keyword can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.

    class MyClass
    {
     static int X = 10;
     int Y = 20;
     public static void Show()
     {
     Console.WriteLine(X);
     Console.WriteLine(Y); //error, since you can access only static members
     }
    }
    

    Key points about Static keyword

    1. If the static keyword is applied to a class, all the members of the class must be static.

    2. Static methods can only access static members of same class. Static properties are used to get or set the value of static fields of a class.

    3. Static constructor can't be parameterized. Access modifiers can not be applied on Static constructor, it is always a public default constructor which is used to initialize static fields of the class.

  9. What is the difference between var data type and anonymous type?

    Var Type

    var data type was introduced in C# 3.0. var is used to declare implicitly typed local variable means it tells the compiler to figure out the type of the variable at compilation time. A var variable must be initialized at the time of declaration.

    Valid var statements

    var str = "1"; 
    var num = 0; 
    string s = "string"; 
    var s2 = s; 
    s2 = null; 
    string s3 = null; 
    var s4 = s3; 

    At compile time, the above var statements are compiled to IL, like this:

     string str = "1"; 
    int num = 0; 
    string s2 = s; 
    string s4 = s3; 

    Anonymous Type

    An anonymous type is a simple class generated by the compiler within IL to store a set of values. var data type and new keyword is used to create an anonymous type.

     var emp = new { Name = "Deepak", Address = "Noida", Salary=21000 }; 

    At compile time, the compiler will create an anonymous type, as follows:

     class __Anonymous1 
    { 
     private string name; 
     private string address; 
     int salary; public string Name
     { 
     get{return name; }
     set { name=value } 
     } 
     public string Address
     { 
     get{ return address; } 
     set{ address=value; } 
     } 
     public int Salary
     { 
     get{ return salary; } 
     set{ salary=value; } 
     } 
    } 

    The anonymous type is very useful when you want to shape the result in your desired form like this:

     var result =from book in Books
     where book.Price > 200 
     orderby book.IssueDate descending 
     select new 
     { 
     Name = book.Name, 
     IssueNumber = "#" + book.Issue
     }; 

    In above example, I change the name of the “Issue” field of Book table to “IssueNumber” and add # before value to get desired output.

  10. What is Type Casting or Type Conversion?

    Type Casting or Type Conversion is a mechanism to convert one data type value to another one. Type conversion is possible if both the data types are compatible to each other; otherwise you will get an InvalidCastException.

    Different Types of Type Casting or Type Conversion

    1. Implicit conversion

      Implicit conversion is being done automatically by the compiler and no data will be lost. It includes conversion of a smaller data type to a larger data types and conversion of derived classes to base class. This is a safe type conversion.

      int smallnum = 654667;
      // Implicit conversion
      long bigNum = smallnum;
      
      class Base
      {
       public int num1 { get; set; }
      }
      class Derived : Base
      {
       public int num2 { get; set; }
      }
      class Program
      {
       static void Main(string[] args)
       {
       Derived d = new Derived();
       //Implicit Conversion
       Base b = d;
       }
      }
      
    2. Explicit conversion

      Explicit conversion is being done by using a cast operator. It includes conversion of larger data type to smaller data type and conversion of base class to derived classes. In this conversion information might be lost or conversion might not be succeed for some reasons. This is an un-safe type conversion.

      long bigNum = 654667;
      // Explicit conversion
      int smallnum = (int)bigNum;
      
      class Base
      {
       public int num1 { get; set; }
      }
      class Derived : Base
      {
       public int num2 { get; set; }
      }
      class Program
      {
       static void Main(string[] args)
       {
       Base b = new Base();
       //Explicit Conversion
       Derived d = (Derived)b; 
       }
      }
      
    3. User-defined conversion

      User-defined conversion is performed by using special methods that you can define to enable explicit and implicit conversions. It includes conversion of class to struct or basic data type and struct to class or basic data type. Also, all conversions methods must be declared as static.

      class RationalNumber
      {
       int numerator;
       int denominator;
       public RationalNumber(int num, int den)
       {
       numerator = num;
       denominator = den;
       }
       public static implicit operator RationalNumber(int i)
       {
       // Rational Number equivalant of an int type has 1 as denominator
       RationalNumber rationalnum = new RationalNumber(i, 1);
       return rationalnum;
       }
       public static explicit operator float(RationalNumber r)
       {
       float result = ((float)r.numerator) / r.denominator;
       return result;
       }
      }
      class Program
      {
       static void Main(string[] args)
       {
       // Implicit Conversion from int to rational number 
       RationalNumber rational1 = 23;
       //Explicit Conversion from rational number to float
       RationalNumber rational2 = new RationalNumber(3, 2);
       float d = (float)rational2;
       }
      }
      
  11. What is the Upcasting and Downcasting?

    There are two more casting terms Upcasting and Downcasting. basically these are parts of Implicit conversion and Explicit conversion.

    Implicit conversion of derived classes to base class is called Upcasting and Explicit conversion of base class to derived classes is called Downcasting.

    class Base
    {
     public int num1 { get; set; }
    }
    class Derived : Base
    {
     public int num2 { get; set; }
    }
    class Program
    {
     static void Main(string[] args)
     {
     Derived d1 = new Derived();
     //Upcasting
     Base b1 = d1;
     Base b2 = new Base();
     //Downcasting
     Derived d2 = (Derived)b2; 
     }
    }
    
  12. What is Boxing and Unboxing?

    Boxing

    Implicit conversion of a value type (int, char etc.) to a reference type (object), is known as Boxing. In boxing process, a value type is being allocated on the heap rather than the stack.

    Unboxing

    Explicit conversion of same reference type (which is being created by boxing process); back to a value type is known as unboxing. In unboxing process, boxed value type is unboxed from the heap and assigned to a value type which is being allocated on the stack.

    Boxing and Unboxing

    For Example

    // int (value type) is created on the Stack
    int stackVar = 12; 
    // Boxing = int is created on the Heap (reference type)
    object boxedVar = stackVar; 
    // Unboxing = boxed int is unboxed from the heap and assigned to an int stack variable
    int unBoxed = (int)boxedVar;
    

    Real Life Example

    int i = 10;
    ArrayList arrlst = new ArrayList();
    //ArrayList contains object type value
    //So, int i is being created on heap
    arrlst.Add(i); // Boxing occurs automatically
    int j = (int)arrlst[0]; // Unboxing occurs
    

    Note

    1. Sometimes boxing is necessary, but you should avoided it if possible, since it will slow down the performance and increase memory requirements.

      For example, when a value type is boxed, a new reference type is created and the value is copied from the value type to the newly created reference type. This process takes time and required extra memory (around twice the memory of the original value type).

    2. Attempting to unbox a null causes a NullReferenceException.

      int? stackVar = null;
      // Boxing= Integer is created on the Heap
      object boxedVar = stackVar;
      // NullReferenceException
      int unBoxed = (int)boxedVar; //Object reference not set to an instance of an object.
      
    3. Attempting to unbox a reference to an incompatible value type causes an InvalidCastException.

      int stackVar = 12;
      // Boxing= Integer is created on the Heap
      object boxedVar = stackVar;
      // InvalidCastException
      float unBoxed = (float)boxedVar; //Specified cast is not valid.
      
 
 
 
Free Interview Books