Data Types

Value Types vs Reference Types

Whenever you need to create a type, first ask yourself a question “What you want and Why you want it?”.

If you could answer your question, you can decide between the type you want to use.

  • If you want to store your data, use value types and when you want to create an instance of your type by defining the behavior, use reference types.
  • Value types are not Polymorphic whereas, the Reference types can be.
  • Value types are most efficient in terms of memory utilization over reference types and produce less heap fragmentation & garbage.
  • If you want to pass values to a method implementation, decide what you want to do and based upon your requirement, decide between value types and reference types.
  • Use of reference type variables actually change the original value but use of value type will create a copy of the original variable and pass across the method. Thus, it protects your original value from accidental changes.

Hence, decide before you start the implementation, else once implemented it will be very difficult to change them over your huge application.

General Tips

  • DO use language keywords instead of BCL types (e.g. int, string, float instead of Int32, String, Single, etc) for both type references as well as method calls (e.g. int.Parse instead of Int32.Parse).

    // Good
    private int _salary = 100;
    
    // Avoid
    private Int16 _salary = 100;
    private Int32 _salary=100;
    
  • DO use nullable data types whenever required.

    You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool, variable can only be either true or false.

    However, in some applications a variable value can be undefined or missing. For example, a database field may contain true or false, or it may contain no value at all, that is, NULL. You can use the bool? type in that scenario.

  • DO use var when the type is explicitly named on the right-hand side, typically due to either new or an explicit cast.

    // Correct
    var stream = new FileStream(...);
    var request = Factory.Create<HttpRequest>();
    
    // For transient variables that are only passed directly to other methods
    var item = GetItem();
    
    // Avoid
    FileStream stream = new FileStream(...);
    var stream = OpenStandardInput();
    
    // Exceptions
    int index = 100;
    string timeSheet;
    bool isCompleted;
    
    • Similarly, target-typed new() can only be used when the type is explicitly named on the left-hand side, in a variable definition statement or a field definition statement.

      e.g. FileStream stream = new(...);,
      
      but not stream = new(...); (where the type was specified on a previous line).
      

    Why: removes clutter, particularly with complex generic types. Type is easily detected with Visual Studio tooltips.

  • DO prefer is and as operators while casting

    It is better to use is and as operator while casting. Instead of Explicit casting, use the Implicit casting.

    // this line may throw Exception if it is unable to downcast from Person to Employee
    var employee = (Employee) person;
    

    In the above code, suppose your person is a Customer type and when you are converting it to Employee type, it will throw Exception and in that case, you have to handle it using try{} catch{} block. Let’s convert the same using is and as operators. See the below code:

    // check if the person is Employee type
    if(person is Employee) (1)
    {
    	// convert person to Employee type
    	employee = person as Employee; (2)
    }
    
    // check if the person is Customer type
    else if(person is Customer)
    {
    	// convert person to Customer type
    	customer = person as Customer; (3)
    }
    
1Checking whether the person is a Employee type.
2If it is of type Employee, it will go into this block.Now, convert it with the as operator. Here, if it is unable to convert, it will return as null but will not throw any exception.So, in the next line, you can check whether the converted value is null. Based on that, you can do what you want.
3Else if it is a Customer type, will go to this block.

Learn More