213

I had read a ton of articles about that new keyword that is shipping with C# v4, but I couldn't make out the difference between a "dynamic" and "var".

This article made me think about it, but I still can't see any difference.

Is it that you can use "var" only as a local variable, but dynamic as both local and global?

Could you show some code without dynamic keyword and then show the same code with dynamic keyword?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Ivan Prodanov
  • 34,634
  • 78
  • 176
  • 248

14 Answers14

472

var is static typed - the compiler and runtime know the type - they just save you some typing... the following are 100% identical:

var s = "abc";
Console.WriteLine(s.Length);

and

string s = "abc";
Console.WriteLine(s.Length);

All that happened was that the compiler figured out that s must be a string (from the initializer). In both cases, it knows (in the IL) that s.Length means the (instance) string.Length property.

dynamic is a very different beast; it is most similar to object, but with dynamic dispatch:

dynamic s = "abc";
Console.WriteLine(s.Length);

Here, s is typed as dynamic. It doesn't know about string.Length, because it doesn't know anything about s at compile time. For example, the following would compile (but not run) too:

dynamic s = "abc";
Console.WriteLine(s.FlibbleBananaSnowball);

At runtime (only), it would check for the FlibbleBananaSnowball property - fail to find it, and explode in a shower of sparks.

With dynamic, properties / methods / operators / etc are resolved at runtime, based on the actual object. Very handy for talking to COM (which can have runtime-only properties), the DLR, or other dynamic systems, like javascript.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 3
    An interesting question would be if there are dynamic ancestors of statically declared classes. Example: class X { public int Y {get;set;} } dynamic(X) s = GetSpecialX(); Calling string test = s.Y; would generate a compiler error because the compiler knows about Y but string test2 = s.Z would compile fine and be checked at run-time. I could think of much value of such half-dynamic classes! – mmmmmmmm Jun 07 '09 at 15:24
  • @rstevens - IIRC, you can add dynamic behaviour via an interface (although there is no direct language support for implementing dynamic types in C# - only consuming them), so this isn't unrealistic... oh the fun we could have ;-p – Marc Gravell Jun 07 '09 at 19:42
  • Although it's important to note that sometimes `var` can infer types that might not be desired because of subtypes and implicit casts. That is, `var` may have resolved a type statically different than expected when *implicit* casts occur (most notably to a more general type, but it's not limited to this). A trivial example is `object x = ""` vs. `var x = ""` vs. `var x = "" as object`, but other more sneaky (and realistic) cases can occur and can cause subtle bugs. –  Jan 10 '11 at 08:46
  • To elaborate further on Marc's good example, in the first case (with static type), the compiler knows exactly which of the [many overloads of `WriteLine`](http://msdn.microsoft.com/en-us/library/system.console.writeline.aspx) to call. This "binding" happens compile-time. In the case with `dynamic`, the type of `.Length` has to be `dynamic` too, and it is not until run-time it is decided which overload (if any at all) of `WriteLine` fits best. Binding happens run-time. – Jeppe Stig Nielsen Nov 19 '12 at 13:09
  • deep dive into what can be done with the dynamic keyword: http://amirrajan.net/Blog/dynamic-c-sharp – Amir Jan 03 '13 at 01:07
  • @MarcGravell: So just to clarify...any object can be assigned to `dynamic`, and if at runtime any method called upon it that __actually exists__ will work? If so..this sounds like it could lead to very dangerous application behavior? – Cody Jan 11 '13 at 23:52
  • @Doctor the method must be accessible to the calling code. Nothing that couldn't already have been called will be called. No danger is introduced. if you call .LaunchMissiles(), then that is a silly thing to do :) – Marc Gravell Jan 12 '13 at 00:27
  • Why `var x = null` can't be implicitly typed as `object`? – cvsguimaraes May 01 '13 at 05:25
  • @cvsguimaraes why would it choose `object`? why not `string`? or `Nullable`? or `dynamic`? The simple answer is that to avoid this ambiguity, the specification does not give a default type to a `null` value. – Marc Gravell May 01 '13 at 11:56
  • 5
    When you hover the `var` keyword in Visual Studio, the actual type is displayed that is being inferred. Shows you that the type is known at compile time. – Christian Fredh Aug 28 '13 at 11:24
  • but in this ex. of `dynamic`, won't calling `s.Length` cause a compile time err as the compiler doesn't know that `dynamic` variable `s` also has the `Length` property associated? – Swaps Jul 09 '16 at 20:33
58

Variables declared with var are implicitly but statically typed. Variables declared with dynamic are dynamically typed. This capability was added to the CLR in order to support dynamic languages like Ruby and Python.

I should add that this means that dynamic declarations are resolved at run-time, var declarations are resolved at compile-time.

Hans Van Slooten
  • 2,257
  • 2
  • 19
  • 18
43

I am going to explain difference between dynamic and var.

dynamic d1;
d1 = 1;
d1 = "http://mycodelogic.com";

This will work. compiler can re-create the type of dynamic variable.
first it create type as integer and after that compiler will recreate type as string
but in case of var

var v1;  // Compiler will throw error because we have to initialized at the time of declaration  
var v2 = 1; // Compiler will create v1 as **integer**
v2 = "Suneel Gupta"; // Compiler will throw error because, compiler will not recreate the type of variable 


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.
var’ keyword, a strongly implicitly typed local variable for which the compiler is able to determine the type from the initialization expression - very useful when doing LINQ programming.
Compiler doesn't have any information about the dynamic type of variable. so compiler will not show any intelligence .
compiler has all information about the stored value of var type so compiler will show intelligence.
dynamic type can be passed as function argument and function also can return object type
But
var type can not be passed as function argument and function can not return object type. This type of variable can work in the scope where it defined.
Darrel Hoffman
  • 4,436
  • 6
  • 29
  • 41
Suneel Gupta
  • 497
  • 5
  • 7
14

var implies that static type checking (early binding) is applied. dynamic implies that dynamic type checking (late binding) is applied. In terms of the code, condsider the following:

class Junk
{
    public void Hello()
    {
        Console.WriteLine("Hello");
    }
}

class Program
{
    static void Main(String[] args)
    {
        var a = new Junk();
        dynamic b = new Junk();

        a.Hello();

        b.Hello();
    }
}

If you compile this and inspect the results with ILSpy, you will find that the compiler has added some late binding code which will handle the call to Hello() from b, whereas becuase early binding was applied to a, a is able to call Hello() directly.

e.g. (ILSpy disassembly)

using System;
namespace ConsoleApplication1
{
    internal class Junk
    {
        public void Hello()
        {
            Console.WriteLine("Hello");
        }
    }
}

using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
    internal class Program
    {
        [CompilerGenerated]
        private static class <Main>o__SiteContainer0
        {
            public static CallSite<Action<CallSite, object>> <>p__Site1;
        }
        private static void Main(string[] args)
        {
            Junk a = new Junk();      //NOTE: Compiler converted var to Junk
            object b = new Junk();    //NOTE: Compiler converted dynamic to object
            a.Hello();  //Already Junk so just call the method.

                          //NOTE: Runtime binding (late binding) implementation added by compiler.
            if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
            {
                Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Hello", null, typeof(Program), new CSharpArgumentInfo[]
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                }));
            }
            Program.<Main>o__SiteContainer0.<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, b);
        }
    }
}

The best thing you can do to discover the difference is to write yourself a little console app like this one, and test it yourself with ILSpy.

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
12

One big difference - you can have a dynamic return type.

dynamic Foo(int x)
{
    dynamic result;

    if (x < 5)
      result = x;
    else
      result = x.ToString();

    return result;
}
user2382351
  • 121
  • 1
  • 3
10

Here is simple example which demonstrates difference between Dynamic (4.0) and Var

dynamic  di = 20;
dynamic ds = "sadlfk";
var vi = 10;
var vsTemp= "sdklf";

Console.WriteLine(di.GetType().ToString());          //Prints System.Int32
Console.WriteLine(ds.GetType().ToString());          //Prints System.String
Console.WriteLine(vi.GetType().ToString());          //Prints System.Int32
Console.WriteLine(vsTemp.GetType().ToString());      //Prints System.String

**ds = 12;**   //ds is treated as string until this stmt now assigning integer.

Console.WriteLine(ds.GetType().ToString());          **//Prints System.Int32**

**vs = 12**; //*Gives compile time error* - Here is the difference between Var and Dynamic. var is compile time bound variable.

Shiva Mamidi

CoolBeans
  • 20,654
  • 10
  • 86
  • 101
Shiva Mamidi
  • 101
  • 1
  • 2
  • 3
    My impression is that the presence of `**` characters in the code example is intended to indicate emphasis only and is not intended to be part of real working code. – DavidRR Oct 01 '15 at 13:21
7

var is just a shorthand for a normal type declaration, where you let the compiler guess the correct type.

dynamic is a new (static) type, where all checks are done at runtime, not by the compiler.

gimel
  • 83,368
  • 10
  • 76
  • 104
5

This is a nice youtube video which talks about var VS Dynamic with practical demonstration.

Below is a more detailed explanation with snapshot.

Var is early binded (statically checked) while dynamic is late binded (dynamically evaluated).

Var keyword looks at your right hand side data and then during compile time it decides the left hand data type.In other words var keyword just saves you typing lot of things. Have a look at the below image where when we have given string data and x variable shows string data type in my tool tip.

enter image description here

On the other hand dynamic keyword is for completely different purpose. Dynamic objects are evaluated during runtime. For instance in the below code the "Length" property exists or not is evaluated during runtime.I have purposely typed a small "l" , so this program compiled fine but when it actually executed it throwed up a error when the "length" property was called ( SMALL "l").

enter image description here

Shivprasad Koirala
  • 27,644
  • 7
  • 84
  • 73
4

The type of a variable declared with var is determined by the compiler, it is a shortcut to specifying the type's name, nothing more.

However dynamic is determined at runtime, the compiler has no idea of the actual type, and all method/field/property accesses with that variable will be worked out at runtime.

Richard
  • 106,783
  • 21
  • 203
  • 265
2

dynamic variable and var variable both can store any type of value but its required to initialize 'var' at the time of declaration.

Compiler doesn't have any information about the 'dynamic' type of variable. var is compiler safe i.e compiler has all information about the stored value, so that it doesn't cause any issue at run-time.

Dynamic type can be passed as function argument and function also can return it. Var type can not be passed as function argument and function can not return object type. This type of variable can work in the scope where it defined.

In case of dynamic Casting is not require but you need to know the property and methods related to stored type , while for var No need to cast because compiler has all information to perform operation.

dynamic: Useful when coding using reflection or dynamic language support or with the COM objects, because we require to write less amount of code.

var: Useful when getting result out of the linq queries. In 3.5 framework it introduce to support linq feature.

Reference : Counsellingbyabhi

Abhishek Gahlout
  • 3,132
  • 2
  • 20
  • 28
2

Here are the differences

  • var is statically typed (compile time), dynamic is dynamically typed (run time)

  • A variable declared as var can only be used locally , dynamic variables can be passed in as params to function (function signature can define a param as dynamic but not var).

  • with dynamic the resolution of the properties happens at runtime and thats not the case with var which means at compile time any variable declared as dynamic can call a method which may or maynot exist and so the compiler would not throw an error.

  • Type casting with var not possible but with dynamic its possible (you can cast an object as dynamic but not as var).

Arun Vijayraghavan

2
  1. Var and dynamic define type.
  2. var at the compile time while dynamic are at run time.
  3. in the var declaration and initialization both are mandatory like constant variable while
  4. in dynamic initialization can be at run time like readonly variables.
  5. in var type whatever type are decided at the time initialization can not change next but
  6. dynamic can adopt any type even user define datatype also.
shhhhh
  • 41
  • 2
1
  1. The Var(Implicit typed local variable) keyword is used to define local variables.In case of Var , the underlying data type is determined at compile time itself based on the initial assignment.Once the initial assignment has been made with Var type , then it will become strongly typed.If you try to store any incompatible value with the Var type it will result in compile time error.

Example:

Var strNameList=new List<string>(); By using this statement we can store list of names in the string format. 
strNameList.add("Senthil");
strNameList.add("Vignesh");

strNameList.add(45); // This statement will cause the compile time error.

But in Dynamic type, the underlying type is determined only at run time.Dynamic data type is not checked at compile time and also it is not strongly typed.We can assign any initial value for dynamic type and then it can be reassigned to any new value during its life time.

Example:

dynamic test="Senthil";
Console.Writeline(test.GetType())  // System.String

test=1222;
Console.Writeline(test.GetType())  // System.Int32

test=new List<string>();
Console.Writeline(test.GetType())  //System.Collections.Generic.List'1[System.String]

It doesn't provide IntelliSense support also.It doesn't give better support when we give work with linq also.Because it doesn't support lambda expressions ,extension methods and anonymous methods.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
kuttychutty
  • 151
  • 1
  • 2
1

Do not confuse dynamic and var. Declaring a local variable using var is just a syntactical shortcut that has the compiler infer the specific data type from an expression. The var keyword can be used only for declaring local variables inside a method while the dynamic keyword can be used for local variables, fields, and arguments. You cannot cast an expression to var, but you can cast an expression to dynamic. You must explicitly initialize a variable declared using var while you do not have to initialize a variable declared with dynamic.

Kartik M
  • 67
  • 2
  • 9