Var Vs Dynamic Keywords In C#

Programming languages can normally be considered to be either statically typed or dynamically typed. A static (not to be confused with the static keyword, used for classes) typed language validates the syntax or checks for any errors during the compilation of the code. On the other hand, dynamically typed languages validate the syntax or checks for errors only at run time. For example, C# and Java are a static type and JavaScript is a dynamically typed language.

C# was previously considered to be a statically typed language, since all the code written was validated at the compile time itself. But, with the introduction of the dynamic keyword in C# 4.0, it became a dynamic typed language also. The two concepts of static and dynamic types in C# can be illustrated with the use of the two keywords named var and dynamic. Let's discuss some basic differences between these two, based on some of their characteristics.

1. When were they introduced

  • var was introduced in C# 3.0
  • dynamic was introduced in C# 4.0

2. Type inference of variables

  • var is a statically typed variable. It results in a strongly typed variable, in other words the data type of these variables are inferred at compile time. This is done based on the type of value that these variables are initialized with.
  • dynamic are dynamically typed variables. This means, their type is inferred at run-time and not the compile time in contrast to var type.

3. Initialization of variables

  • var type of variables are required to be initialized at the time of declaration or else they encounter the compile time error: Implicitly-typed local variables must be initialized.
  • dynamic type variables need not be initialized when declared.

4. Changing type of value assigned

  • var does not allow the type of value assigned to be changed after it is assigned to. This means that if we assign an integer value to a var then we cannot assign a string value to it. This is because, on assigning the integer value, it will be treated as an integer type thereafter. So thereafter no other type of value cannot be assigned. For example, the following code will give a compile time error:

    var

  • dynamic allows the type of value to change after it is assigned to initially. In the code above, if we use dynamic instead of var, it will not only compile, but will also work at run-time. This is because, at run time, the value of the variable is first inferred as Int32 and when its value is changed, it is inferred to be a string type.

    dynamic

5. Intellisense help

  • Intellisense help is available for the var type of variables. This is because, its type is inferred by the compiler from the type of value it is assigned and as a result, the compiler has all the information related to the type. So we have the intellisense help available. See the code below. We have a var variable initialized with a string value. So its type is known to the compiler and we have the appropriate intellisense help available for it.

    Intellisense

  • Intellisense help is not available for dynamic type of variables since their type is unknown until run time. So intellisense help is not available. Even if you are informed by the compiler as "This operation will be resolved at run-time". See the code below :

    Intellisense help is not available for dynamic type

6. Restrictions on the usage

  • dynamic variables can be used to create properties and return values from a function.
  • var variables cannot be used for property or return values from a function. They can only be used as local variable in a function.

var vs dynamic vs object

If we closely observe the dynamic type, it is performing pretty much the same task that the object type (which is the base type of all other types) does. Then what is the difference between an object type and a var then? Also, why we need a var when we have the object type. Let's discuss these points by doing some comparisons.

  1. When using an object type, the compiler provides only generic information, functionality or functions related to the type it holds, until it is being type cast into its actual type. This means that even if we have stored integer or string values in an object type, we will get their related functions, only if we convert the object type into its actual type. See the code below:

    object

    Here, we only have generic properties and functions available for the type of value stored in it, that we will have, even if we store an integer or other type of value in it. Now, let's convert it to its actual type, string.

    properties

    Now after explicit conversion, we have the properties and functions specific to the string type. In case we use the var type to store the same value, we would not be required to do the explicit conversion, since the compiler already infers its type from the value initialized and we will have its functions and properties.
     
  2. Based on the preceding point, object types increase the overhead of boxing and un-boxing, before we can use the actual values stored in it or use any function related to it. But this is not the case with var, since we already know its type at the time of use. For example, in the code above, we get to use the functions related to a string only after we convert the object into a string. So this results in un-boxing. On the other hand, for dynamic types, we only need to know that the function or property we are using actually exists for the type of value being stored in it.

    dynamic types

    For example, in the code above, if we know that the dynamic variable will be storing a string type, then we can use the Length type property, even if it is not available in the intellisense help.
     
  3. Next, we need to be careful when casting or converting the values, when using the dynamic or object type variables. Any incorrect casting can result in runtime errors. On the other hand, a var type will give a compile time error for an incorrect conversion. So a run time error is not possible.

    run time error

    Here, the object type is stored as a string value, but we are trying to cast into an integer type. So it will throw a run time error.

    error

    Similarly, we are storing back the string value, into an integer type. So it would again result in an error.
     
  4. In terms of interoperability with various frameworks, earlier we required an object type to be used to get the underlying object type and then use reflection to access the related methods or functions. But with the introduction of the dynamic keyword, we only need to know that a function or property exists on the underlying object and the rest we simply need to make a call to these properties or functions.
     
  5. As per MSDN, "As part of the process, variables of type dynamic are compiled into variables of type object. Therefore, type dynamic exists only at compile time, not at run time.".

From these points, we cannot conclude which specific type we should use. It all depends on the requirements whether we should go for a var or dynamic or object type.

So this was all about the basic differences between var and dynamic keywords. I hope you enjoyed reading it.