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?
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.
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.
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 typeButvar 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.
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.
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;
}
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
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.
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.
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").
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.
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
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
Var and dynamic define type.
var at the compile time while dynamic are at run time.
in the var declaration and initialization both are mandatory like constant variable while
in dynamic initialization can be at run time like readonly variables.
in var type whatever type are decided at the time initialization can not change next but
dynamic can adopt any type even user define datatype also.
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.
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.
Related
I have C# ArrayList and added two items int and string type
Now in for loop Item returns and captured in var type at run time.
How this var type decide data type at compile time????
ArrayList al = new ArrayList();
al.Add(10);
al.Add("A");
for(int i=0; i<2;i++)
{
var val = al[i];
Console.WriteLine("type of value is {0} and {1}",val.GetType(),val);
}
var is used for type inference at compile time. The compiler determines the variable type given all the information it has about the expression al[i] at that time.
Since the indexer property of ArrayList is of type object, the compiler infers the type of val to be object.
At runtime, when calling val.GetType() you have access to the actual type of val: either int or string in your case. But the type of the val variable is still object.
The same mechanism happens if you write:
object o = new int();
Console.WriteLine(o.GetType());
You'd see "System.Int32" although the type of o is object.
Link to fiddle
var is purely compiler "magic", nothing special happens at runtime.
It's your way of saying "compiler, you figure out the correct data type for this variable declaration. I either don't want to, am not too concerned about the specific type, or it's got an unpronounceable name1"
So, the compiler first works out the data type of the expression that's being used to initialize the variable, and gives the variable that type.
Here, the expression's simple - you're accessing the Item property of ArrayList via C#'s indexer syntax. That property returns object, so that's the type of the val variable.
All of that happens at compile time.
1When LINQ was introduced, anonymous types arrived in the language. These are real types generated by the compiler, but they're deliberately given names that, whilst valid names so far as the CLR is concerned, aren't valid names so far as C# is concerned. You don't know their names and even if you did, you wouldn't write them in C#.
It's why var had to be added to the language, the other reasons are convenient outcomes of that decision.
As other said here ArrayList implementation is based on object. Var only infers the type of the right side of the assignment, which in this case is a type of an object, feel free to use in this case object. You should not get any exception. Because ArrayList has not a generic implementation you need to unbox the items to a specific type if you want to treat them differently.
Basically you have a similar effect using a generic list of object.
Here is the implementation of the class, so you can see by yourself the internal implementation
https://referencesource.microsoft.com/#mscorlib/system/collections/arraylist.cs
Hope this helps
In the following code snippet why does the implicitly typed variable be determined as a dynamic instead of the method's return type of FluentClass?
public static class DynamicTest
{
public class FluentClass
{
public FluentClass SomeMethod(dynamic arg)
{
return this;
}
}
public static void Main()
{
dynamic data = new { Data = 1 };
var fluentClass = new FluentClass();
// fluentClass variable is typed FluentClass
var methodResult = fluentClass.SomeMethod(data);
// methodResult variable is typed dynamic
}
}
Why does a method that returns a type result in an implicit typing of dynamic?
Because that's the best the compiler can do, given the information it has.
The reason methodResult is dynamic is that the entire expression used to initialize it is dynamic. And that's the case, because data is dynamic.
When you use dynamic, you're telling the compiler to not resolve types at compiler time. Instead, they should be resolved according to the normal compiler rules, but at run-time.
The fluentClass variable could hold some implementation of FluentClass that contains an overload that matches the run-time type of the argument data. In that case, a different implementation of SomeMethod() could be called, returning a different type.
You've told the compiler to defer type resolution to run-time, so it can't force things back into a strongly-typed context unless you tell it explicitly what type things are. In your example, it can't, so the type remains dynamic.
Note that you might have thought that the compiler would identify the one overload you've provided, based on its parameter type of dynamic. But that's not how dynamic works. The dynamic parameter affects only the implementation of the method, i.e. the code in its body. As far as calling the method goes, the parameter is essentially object. It's just that when the parameter value is used in the method body, it has the features of dynamic.
Another way to think of dynamic is that it accepts any object as input (like object), but then allows you to use any member of that object that you believe exists (if it doesn't exist an exception will be thrown at run-time). Using dynamic defers the compiler logic downstream, i.e. for the output of any usages of the dynamic variable, but doesn't affect the input, i.e. the assignment of that variable.
Note also that even if the method call is completely unambiguous, e.g. a static method where there's only one method with that name, you'll still get a dynamic result. Once you start using dynamic, it sticks with you until you provide an explicit cast to get back to a known type.
Related reading:
Very similar to your question, if not actually duplicates:
Why does a method invocation expression have type dynamic even when there is only one possible return type?
Why does this method keep returning dynamic despite the return type in the signature?
Why doesn't this string.Format() return string, but dynamic?
More general discussion of dynamic:
What is the 'dynamic' type in C# 4.0 used for?
C# 4: Real-World Example of Dynamic Types
How can I use a dynamic as a generic?
This
var x = something not strongly typed;
callFunction<x>();
and this
dynamic x = something not strongly typed;
callFunction<x>();
both produce this error
Error 1 The type or namespace name 'x'
could not be found (are you missing a using directive or an assembly reference?)
What can I do to x to make it legitimate enough to be used in <x>?
You could use type inference to sort of trampoline the call:
dynamic x = something not strongly typed;
CallFunctionWithInference(x);
...
static void CallFunctionWithInference<T>(T ignored)
{
CallFunction<T>();
}
static void CallFunction<T>()
{
// This is the method we really wanted to call
}
This will determine the type argument at execution time based on the execution-time type of the value of x, using the same kind of type inference it would use if x had that as its compile-time type. The parameter is only present to make type inference work.
Note that unlike Darin, I believe this is a useful technique - in exactly the same situations where pre-dynamic you'd end up calling the generic method with reflection. You can make this one part of the code dynamic, but keep the rest of the code (from the generic type on downwards) type-safe. It allows one step to be dynamic - just the single bit where you don't know the type.
It's hard to tell what exactly are you trying to do. But if you want to call a generic method with a type parameter that is the same as some object, you can't do that directly. But you can write another method that takes your object as a parameter, let the dynamic infer the type and then call the method you want:
void HelperMethod<T>(T obj)
{
CallFunction<T>();
}
…
dynamic x = …;
HelperMethod(x);
You can't. The whole point of generics is compile-time safety which means that they must be known at compile-time. And the whole point of dynamics is that you don't need to know the exact type at compile time and use runtime dispatching => it's the absolutely exact opposite of generics. So don't waste your time => once you get the dynamic/reflection path you can forget about generics and compile-time safety. You will have to walk that path till the end.
So to answer your question:
What can I do to x to make it legitimate enough to be used in ?
The only thing you could do is to use a type that is known at compile-time, otherwise you cannot use generics.
You get that error because x is not a type. You need to specify a type as a type parameter.
In fact, you can use dynamic as a type parameter if you use it correctly:
var dict = new Dictionary<string, dynamic>();
dict.Add("Item1", 123);
dict.Add("Item2", "Blah");
This compiles and runs just fine.
The quickest way to make this work is to make your anonymous type a real type.
So instead of
var x = new { Value = "somevalue", Text = "sometext" };
You need to do
class MyClass
{
string Text, Value;
}
....
var x = new MyClass() { Value = "somevalue", Text = "sometext" };
//this should work now
callFunction<MyClass>(x);
You should be able to call the function like this
callFunction<dynamic>();
If your function is defined as
public void callFunction<T>(T arg) {
...
}
You can simply call it with
callFunction(x);
C# is able to infer generic type parameters in many situations.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Using var outside of a method
class A {
string X;
}
// Proper
class A {
var X;
}
// Improper (gives error)
Why is it, that i cant have var type variable declare in Class and what can be done in order to achieve it OR what is an alternative ?
In function/method, i can declare a var type variable,then why can't, i do it in class ?
Thanks.
// method variable
var X;
is never valid - even inside a method; you need immediate initialization to infer the type:
// method variable
var X = "abc"; // now a string
As for why this isn't available for fields with a field-initializer: simply, the spec says so. Now why the spec says so is another debate... I could check the annotated spec, but my suspicion would be simply that they are more necessary for method variables, where the logic is more complex (re LINQ etc). Also, they are often used with anonymous types (that being the necessity for their existence); but anonymous types can't be exposed on a public api... so you could have the very confusing:
private var foo = new { x = 123, y = "abc"}; // valid
public var bar = new { x = 123, y = "abc"}; // invalid
So all in all I'm happy with the current logic.
If you really don't know the type of object your instance variable will hold, use object, not var. var doesn't mean "i don't know", it means "infer the type for me" - this is why it can never be used on class members.
Because C# doesn't support this level of type inferencing. Your alternatives are to use a language, such as F#, that does support this level of type inferencing or beg the C# team to implement the feature. I've got a pretty good guess which one you'll have more luck with...
var in C# is a implicitly typed local variable used to infer the type from the RHS of the given expression, which needs to be resolved at compile time. When you declare a var with no RHS value in the class definition, there is no way for the compiler to know the type that you are trying to assign to var.
C# doesn't support implicit typing for class variables.
Because the actual type of a var is inferred from the context in which it is used. For fields (class member variables), there is no such context.
You can argue that the intent is quite obvious if you would write var _users = new List<User>() as a field declaration.
The problem is that not all field declarations contains an assignment which is required to infer the type. (You might want to initialize a field through the constructor)
Mixing both var and normal type declarations would look like a nasty soup. Therefore it's not possible.
(at least that's my guess)
Yes, the var keyword is only allowed for local variables.
It was introduced in the language to be able to handle an anonymous type, that only exists in a local scope. As the anonymous type is limited to the local scope, it makes sense to only allow the var keyword in a local scope.
Additionally, it never works to use the var keyword without specifying a value, as that is used to infer the data type:
var x = "asdf"; // works
var x; // doesn't work
The normal way of declaring a variable is using a specific data type. Use the var keyword when you can't specify a data type (e.g. when the type is anonymjous) or when the type is superflous (e.g. repeated literally in the value). Example:
var x = new { Key = 42, Name = "asdf" };
var y = new System.Text.StringBuilder();
It is all because of the Build order. You can declare var in only methods. Compiler builds everything but methods first and thats why the type of the object will be clear to the compiler if you use it inside of a method. Jon had a great answer about this but can't seem to find.
I have used the dynamic and the object type interchangeably. Is there any difference between these two types? Is there any performance implications of using one over the other? Which one of these is more flexible?
They're hugely different.
If you use dynamic you're opting into dynamic typing, and thus opting out of compile-time checking for the most part. And yes, it's less performant than using static typing where you can use static typing.
However, you can't do much with the object type anyway - it has hardly any members. Where do you find yourself using it? When you want to write general purpose code which can work with a variety of types, you should usually consider generics rather than object.
With the advancement in C# language, we have seen the dynamic and object types. Here are the two types, as I learned by comparing these 7 points:
Object
Microsoft introduced the Object type in C# 1.0.
It can store any value because "object" is the base class of all types in the .NET framework.
Compiler has little information about the type.
We can pass the object type as a method argument, and the method also can return the object type.
We need to cast object variables to the original type to use it and to perform desired operations.
Object can cause problems at run time if the stored value is not converted or cast to the underlying data type.
Useful when we don't have more information about the data type.
Dynamic
Dynamic was introduced with C# 4.0
It can store any type of variable, similar to how Visual Basic handles a variable.
It is not type-safe, i.e., the compiler doesn't have any information about the type of variable.
A method can both accept a Dynamic type as an argument and return it.
Casting is not required, but you need to know the properties and methods related to stored type.
The Dynamic type can cause problems if the wrong properties or methods are accessed because all the information about the stored value is resolved at run time, compared to at compilation.
Useful when we need to code using reflection or dynamic languages or with the COM objects due to writing less code.
Hopefully, this would help somebody.
In simple language:
Assume we have the following method:
public static void ConsoleWrite(string inputArg)
{
Console.WriteLine(inputArg);
}
Object: the following code has compile error unless cast object to string:
public static void Main(string[] args)
{
object obj = "String Sample";
ConsoleWrite(obj);// compile error
ConsoleWrite((string)obj); // correct
Console.ReadKey();
}
dynamic: the following code compiles successfully but if it contains a value except string it throws Runtime error
public static void Main(string[] args)
{
dynamic dyn = "String Sample";
ConsoleWrite(dyn); // correct
dyn = 1;
ConsoleWrite(dyn);// Runtime Error
Console.ReadKey();
}
There is an article explaining the different types, including object and dynamic types. The article also explains the difference between the two with a nice example.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types
I shall give a short gist of the difference explained in the article:
The object type is an alias for System.Object in .NET. In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from System.Object. You can assign values of any type to variables of type object.
The dynamic type indicates that use of the variable and references to its members bypass compile-time type checking. Instead, these operations are resolved at run time. The dynamic type simplifies access to COM APIs such as the Office Automation APIs, to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).
Type dynamic behaves like type object in most circumstances. In particular, any non-null expression can be converted to the dynamic type. The dynamic type differs from object in that operations that contain expressions of type dynamic are not resolved or type checked by the compiler. The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. 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.
Summary:
What this essentially means is object is a type and all other types inherit from it.
Dynamic is not really a type, it is more like a pointer or representation of some other type, which will be resolved at run time.
Dynamic: Casting is not required but you need to know the property and methods related to stored type to avoid error in run time.
dynamic dyn = 1;
Console.WriteLine(dyn);
int a = dyn;// works fine
Console.WriteLine(a);//print 1
Console.ReadKey();
The above code will work just fine but if dyn = 1.2 is supplied then it will throw exception as 1.2 cannot converted to int
Object: Require to cast object variable explicitly.
object ob = 1;//or 1.2
Console.WriteLine(ob);
int a = ob;//Compile error because explicit casting is not done
Console.WriteLine(a);
Console.ReadKey();
Fiddle: https://dotnetfiddle.net/l5K4Cl