Differences between Var, Dynamic and Object
var is used to store an anonymous type or a collection of anonymous types, and scope limited to within the declared method. Dynamic type variables type checking is done at run-time and can be initialized by any type of data. Object is basically a block of memory that has been configured according to the blueprint.
Collections and Collection Interfaces
Var Dynamic Object Can store any type but mandatory to initialize the var type at the time of declaration
Can store any type of the variable
Can store any kind of value as this is the base for all types in .NET
It is type safe as compiler has all information of the stored value. No issues are run time
It is not type safe as compiler won't have any information until run time about variable type
Compiler has little information about the type
The scope of this type is limited to where it is defined. Neither be passed as argument nor used as return type
This can be passed as argument as well as can be used as method return type
This can be passed as argument as well as can be used as method return type
Casting is not required at anytime as compiler has all the information
Casting is not required but should be aware of properties and methods related to the stored type
Casting is required to original type to use it and perform operations
No problems as compiler has all the information
Causes problems, If wrong properties or methods are accessed as all the information will be resolved at run time
Causes problem at run time if the value is not getting converted to base data type
Introduced in C# 3.0 and useful cases of anonymous type scenarios
Introduced in C# 4.0 and useful in cases of working with Reflection, COM or dynamic languages
Introduced in C# 1.0 and sseful in cases where we don't know any information about the type
Virtual, Override, and New keywordsCollections: Collection refers to a set of objects. These can grow and shrink dynamically as the objects added or deleted. Collection is basically a class, so needs to be declared before one can add elements to that. System.Collections namespace contains below collections:
- ArrayList: Represents an array of objects whose size is dynamically increased or decreased as required. It supports add or remove methods for adding and removing objects from the collection.
- Hashtable: Also represents a collection of objects which are stored in key/value pair, where key is a hash code and value is an object. Using key one can access the objects in the collection. Also supports add and remove methods for adding and removing objects from the collection.
- SortedList: This collection is a combination of ArrayList and Hashtable and along with can be sorted by the keys. It can be accessible by key or by index. Also supports add and remove methods for adding and removing objects from the collection.
- Stack: Represents a LIFO (Last In First Out) collection of objects. It supports Push and Pop methods for adding and removing objects from the collection.
- Queue: Represents a FIFO (First In First Out) collection of objects. Supports Enqueue and Dequeue methods for adding and removing objects from the collection.
Collection Interfaces: All the collection types use common interfaces which define the basic functionality for each collection class. Below are the key collection classes. IEnumerable acts as a base interface for all the collection types which is extended by ICollection which is further extended by IDictionary and IList interfaces. All collection interfaces are not implemented by all the collections. It depends on the nature of collection.
- IEnumerable: Provides an enumerator which supports a simple iteration over a non generic collection
- ICollection: Defines size, enumerators and synchronization methods for all nongeneric collections
- IDictionary: Represents nongeneric collection of key/value pairs
- IList: Represents nongeneric collection of objects that can be individually accessed b index
All these three keywords will help support working with Polymorphism which is nothing but method overriding and method overloading. Virtual and Override keywords support method overriding whereas New keyword supports method hiding.
Virtual: this keyword lets a method, property, indexer or event declared in the base class to be overridden or modifying the functionality in the derived class.
Override: this keyword lets to extend or modify a base classes method, property, indexer or event in derived class.
New: this keyword lets to hide a method, property, indexer or event declared in the base class in to derived class.
- Virtual and Override causes late binding and is called as runtime poluymorphism. This takes same name as base class with same parameters
- New causes early binding and also called as compile time polymorphism. This takes same name as base class with different parameters
This is a mechanism to convert one data type value to another data type, and is possible only if both the data types are compatible to each other. Otherwise InvalidCastException will be thrown. Below are the different type of conversions:
Is vs As
- Implicit Conversion: This is being handled automatically by the compiler with no data lose. This is safe type conversion and includes converting smaller to larger data types as well as derived classes to base classes. This is also called as Upcasting.
- Explicit Conversion: This is being done by using a cast operator. In this type of conversion data might be lost or conversion might not be succeed for some reasons and not an type safe conversion. Also supports converting smaller to larger data types as well as derived classes to base classes. This is also called as Downcasting.
- User-defined Conversion: This conversion is performed by using special methods that you can define to enable explicit and implicit conversions. In this type, all conversions methods must be declared as static. It includes conversion of class to struct or basic data type and struct to class or basic data type.
IS and AS operators are helpful to handle the exceptions occurred during casting / converting one data type to another data type. These are helpful to do a safe type casting. Usually exceptions occur when the new data type is not compatible with the given object data type.
IS Operator: This operator checks whether both given object and the new object type is compatible or not. It returns boolean (True / False) value as a result. In case of a given object is null, this will return false as there is no object to check for type. The drawback of using this operator is, the Performance. As every time CLR checks for each base type with the specified type following the inheritance hierarchy. Below is how to use IS operator:
Object obj = new Object(); // Creates a new Object
Boolean isCompatible = (obj is Organization); // No exception in this case but sets isCompatible as False
If (isCompatible) { Organization org = (Organization) obj; }if (obj is Organization) { Organization org = (Organization) obj; }( OR )
AS Operator: Like IS operator, AS operator also helps to check the type of a given object is compatible with new object type. Instead of boolean, this returns NON-NULL if given object is compatible else NULL as result. This operator performs only reference conversions, nullable conversions and boxing conversions, and cannot perform user-defined conversions. Using this, CLR checks object type for only one time. So, AS operator provide good performance over IS operator.
Object obj = new Object(); // Creates a new Object objBoxing and Unboxing
Organization org = obj as Organization; // This cast fails, but no exception is thrown and org will set to NULL
If (org != null) { // Execute your code here }
These always refers to the allocation of a value on the Heap rather than on the Stack.
Boxing: Refers to an Implicit conversion of a value type to a reference type. Basically in this process, a value type is being allocated on Heap rather from Stack
Unboxing: Refers to an Explicit conversion of a reference type to a value type. Basically in this process, a reference type is being allocated back to Stack from Heap
int curValue = 12; // value type which will be created on Stack
Object retBoxed = curValue;
int retUnboxed = (int) retBoxed; // Unboxed from heap to Stack
- Try to eliminate using Boxing as it slows down the performance and increases memory usage
- NullReferenceException will be thrown by compiler in case of unboxing a null
- InvalidCastException will be thrown by compiler in case of unboxing a reference type to an incompatible value type
Constants: These must be assigned a value at the time of declaration and after that they cannot be modified.ref and out parameters
ReadOnly: These can be initialized either at the time of declaration or with in the constructor of the defined class.
- These are Static by default, so no need to declare them using static keyword
- They must have a value at compilation time
- Can be declared within functions and be used as Attributes
- These can be declared as pubic, private, protected, internal or protected internal access modifiers
Static: This is used to specify a static member, meaning these are common to all the objects and they do not tied up to a specific object.
- Must have set the value by the time constructor exists
- As these are not static by default, one need to define them using static keyword if they want this type of variable to be static
- Will be evaluated when instance is created
- Use this modifier when one want to make a field constant at run time
- ReadOnly can be applied to Value and Reference types but not to delegates and events
When to use what:
- Evaluated when code execution hits class reference ie. when new instance is created or a static method is executed
- Must have a value by the time the static constructor is done
- These can be used with classes, fields, methods, properties, operators, events and constructors, but no on indexers, destructors or other than classes
- If we know the value will never ever change use const
- If we re unsure that the value will change, and you don't want other classes or code to be able to change it, use readonly
- If we need a field to be a property of a type, and not a property of an instance of that type, use static
Both ref and out parameters are used to pass an argument within a method.
ref: the ref keyword is used to pass an argument as a reference, which means that when a value of the parameter is changed then it gets reflected in the calling method. An argument which is passed using a ref keyword must be initialized in the calling method before it is passed to the called method.
public static string GetNextName(ref int id)
{
string returnText = "Next-" + id.ToString();id += 1;return returnText;}
static void Main(string[] args)
{
int i = 1;Console.WriteLine("Previous value of integer i:" + i.ToString());string test = GetNextName(ref i);Console.WriteLine("Current value of integer i:" + i.ToString());}
out: the out keyword is also used to pass an argument like ref but can be passed without assigning any value to it. An argument that is passed using an out keyword must be initialized in the called method before it returns back to calling method.
public static string GetNextNameByOut(out int id)
{
id = 1;string returnText = "Next-" + id.ToString();return returnText;}
static void Main(string[] args)
{
int i = 0;Console.WriteLine("Previous value of integer i:" + i.ToString());string test = GetNextNameByOut(out i);Console.WriteLine("Current value of integer i:" + i.ToString());}
No comments:
Post a Comment