Sunday, September 28, 2014

Objec Vs Var Vs Dynamic


System.Object

All the objects (value and referenced types) in managed environment are directly or indirectly inherit from System.Object. With this inheritance in place, a variable of System.Object can hold instance of any type.

However compiler will allow to call only those methods /properties which exists in System.Object type. 
In other words compiler will not allow you to call CreateNode property from obj. The only way to access the CreateNode() is to typecast it into XmlDocument type. 
E.g. System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
            object obj = xDoc;

Hence:
a.      Though variable of System.Object type can hold the reference of any type, compiler will ensure the type safety. If type casting is happening, compiler will emit the code to validate the type safety during runtime.
b.      Assigning the value type to a variable of System.Object will suffer from Boxing / Unboxing.



Var Keyword

The var keyword was introduced in C# 3.0. It was primarily introduced to support the notion of anonymous types.
var is resolved at the compile time, i.e., the actual type is resolved by the compiler during the compile time. Hence it provides same type safety as using normal typed variable.

Hence,
a.      var is a compile time feature resolved to a valid underlying type. Due to this, compiler enforces you to assign a value during the declaration so it can infer the actual type.
b.      Since var is resolved to a valid type during compilation, compiler will enforce all type safety and code will not suffer from boxing / unboxing.


Dynamic

dynamic keyword was introduced with C# 4.0. When you define a variable of type dynamic, compiler internally performs two steps. The first thing compiler does is, it converts the type to System.Object and then it postpones all the type validation to the runtime.

Hence
1.      During compilation time, dynamic is converted to System.Object and compiler will emit the code for type safety during runtime.
2.      As dynamic is treated as System.Object, it suffers from boxing / unboxing similar to System.Object.
3.      Since compiler emits the code for all the type safety, application’s performance will suffer.
dynamic was introduced only to simplify the access to the COM APIs.

To put it as simple as possible, there is a simple difference between the C# ‘var’ and ‘dynamic’ keyword. When using the ‘var’ keyword, the type is decided by the compiler at compile time, whereas when using the ‘dynamic’ keyword, the type is decided by the runtime.

C# is a statically typed language and the ‘dynamic' type automatically tells the compiler that it is a dynamic invocation, so ignore the compile time checking for this type. This also means that any invalid operations will only be detected at runtime.

E.g. Consider following example
var emp = new Employee();
emp.AddEmployee();
In this case, i.e. when you are using the ‘var’ keyword, the type is statically inferred. So the line of code evaluates as
Employee emp = new Employee();
The compiler will check to see if a AddEmployee () method exists, if not, fail the compilation.

Consider following case
dynamic emp = new Employee();
emp.AddEmployee();
Using the ‘dynamic’ type does not make it type-safe, hence the compiler is bypassed and the compiler does not check if the AddEmployee () method exists.

Anonymous Types


Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first

i.e. We cannot update value of anonymously typed object. We can use it only for Read-only purpose.

Anonymous types typically are used in the select clause of a query expression to return a subset of the properties from each object in the source sequence.

Anonymous types contain one or more public read-only properties. No other kinds of class members, such as methods or events, are valid. 
The expression that is used to initialize a property cannot be null, an anonymous function, or a pointer type.

The most common scenario is to initialize an anonymous type with properties from another type. If you do not specify member names in the anonymous type, the compiler gives the anonymous type members the same name as the property being used to initialize them.
var customerQuery = from cust in customers
                    select new { cust.Name, cust.OrderAmount };

            foreach (var c in customerQuery)
            {
                Console.WriteLine("Name={0}, Bill Amount={1}", c.Name, c.OrderAmount);
            }

You must provide a name for a property that is being initialized with an expression.
var customer = new { Name = "Naren", Age = 27 };


Note:
Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object. The compiler provides a name for each anonymous type, although your application cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other reference type.

If two or more anonymous object initializers in an assembly specify a sequence of properties that are in the same order and that have the same names and types, the compiler treats the objects as instances of the same type. They share the same compiler-generated type information.

var - Implicitly Typed Local Variables


 The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type.

E.g. ways in which local variables can be declared with var
var a = 1; // a is compiled as int
var b = "Narendra"; // b is compiled as string
var c = new List<int>(); // c is compiled as List<int>
var d = new { Name = "Naren", Age = 27 }; // d is compiled as an anonymous type

It is important to understand that the var keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.

E.g. var myVariable = 1; // myVariable is compiled as int
If I try to assign it differnt value than int as  :
myVariable = "some string"; then it will throw error as " Error: Cannot implicitly convert type 'string' to 'int' "               

Following restrictions apply to implicitly-typed variable declarations:
·         var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.

NOTE: The compile-time type value of var variable cannot be null but the runtime value can be null.
E.g. If we try var a = null; It throws error " Error: Cannot assign <null> to an implicitly-typed local variable."
But following is valid statement
           string s=null;
            var a = s;            
·         var cannot be used on fields at class scope.
·         Multiple implicitly-typed variables cannot be initialized in the same statement.
            E.g. var param1 = 1, param2 = 2; --> This is not allowed. This will throw compilation error "Error: Implicitly-typed local variables cannot have multiple declarators"
Following is valid declaration.
  var param1 = 1;
 var param2 = 2;