When you use the var keyword, you tell the compiler to automatically determine the type of the variable based on the value assigned.
When you use the dynamic keyword you tell the compiler to turn off compile-time checking. However the type checks still do happen during runtime, and instead of compile time errors, you get runtime errors.
The following code won't compile as the compiler has inferred the value of v to be string, and ++ is not defined for a string.
var v = "some string"; //compiler infers type of v is string v++; // compiler error here. The code does not compile.
The below code compiles fine as the compiler checks are turned off for dynamic. However if we run it, we will get a Runtime exception when we attempt to increment a string.
dynamic d = "some string" d++;
For var the type of the variable is determined at the time of declaration and the type does not change throughout the lifetime of the variable. However for a variable declared using the dynamic keyword, the variable can assume different underlying types.
dynamic d = "some string"; // d is string d = 100; // d is now int
With dynamic we lose compile time checks, so it is generally advised to avoid using dynamics unless necessary. Following quote from MSDN nicely summarized when use of dynamics is justified:
As a developer, you use the dynamic keyword with variables expected to contain objects of uncertain type such as objects returned from a COM or DOM API; obtained from a dynamic language (IronRuby, for example); from reflection; from objects built dynamically in C# 4.0 using the new expand capabilities.
var shortLivedObject = new ShortLivedObject(); mainForm.SomeEvent += shortLivedObject.HandleSomeEvent;Now say after a short while shortLivedObject is not needed and is either disposed off or goes out of scope and there are no other variables pointing to this instance. We would then expect the garbage collector to free up the memory allocated for it when it runs. However Garbage Collector is unable to do so as mainForm.SomeEvent still has an active reference to this instance (more specifically the handler which resides in this instance). So it cannot clean it up till the mainForm object is destroyed. We have a leak.
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(someObject));The memory allocated by the above statement will remain allocated throughout the life of the application, unless you call
Marshal.FreeHGlobal(ptr);
Other Instances of Leak
Superficially, both interfaces and abstract classes are look similar, but there are a few important differences:
An interface is a contract, and any class which implements the interface has to abide by the contract by providing an implementation of the methods and/or properties which the interface declares. An interface cannot contain any code. A class can implement any number of interfaces.
An abstract class is a class which cannot be instantiated. It contains at least one abstract method (method with no definition) or property and can contain members and other function definitions like a normal class (in c# a class can be marked as abstract even if it doesnt have any abstract members). A class cannot implement more than one class (abstract or not).
Interlocked class provides a set of static functions which allow a few simple operations to be performed thread safe. Apart from convenience, these functions are much faster than having a lock around an equivalent statement (explained below). First, following is a list of Interlocked functions with explanation in comments.
long counter = 0; //Increment counter by 1 Interlocked.Increment (ref counter); //Decrement counter by 1 Interlocked.Decrement (ref counter); //Add 10 to counter Interlocked.Add (ref counter, 10); //Set counter = 100 and return the original value of counter before it was changed. //This usually does not require a lock but consider a scenario where //counter is a 64 bit value and code running on a 32 bit machine. //In such a scenario the assignment happens in 2 steps for each 32 bit part //and hence the assignment is not atomic. var oldCounterValue = Interlocked.Exchange (ref counter, 100); // Read a 64-bit value atomically into another variable (val) var val = Interlocked.Read(ref counter); // Set counter = 999 if counter == 1000 Interlocked.CompareExchange(ref counter, 999, 1000);
As I mentioned these statements are faster in most cases and especially on modern CPUs, as these functions execute in a lock free manner or as a single instruction wherever possible, thus avoiding the need for a lock (they do use memory barriers though, to avoid reordering issues etc.) For example CompareExchange function uses the cpu instruction CMPXCHG which allows Comparison and Exchange of values in a single instruction which cannot be pre-empted.