From csharpfaq: What is the difference between "dynamic" and "object" keywords?
Let's take a quick look at the object keyword first. I won't talk too much about it, because it already exists in C #1.0. This keyword serves as a shortcut for system. Object. system. object is the root type at the C # class level. (However, as Eric lippert pointed out in his blog, not all types are inherited from object [Chinese] [English]). This is a powerful mechanism, in this way, you can allocate almost any instance value to this type.
This is a small example to demonstrate the benefits and problems of using the object keyword.
Object OBJ = 10;
Console. writeline (obj. GetType ());
// Output system. int32 because
// This is the type of the value stored in this object.
// A compilation error because
// The OBJ type is system. object during compilation.
// OBJ = OBJ + 10;
// You need to explicitly convert OBJ to the expected type.
OBJ = (Int) OBJ + 10;
// However, this does not mean you are actually safe.
// You may convert to an incorrect type
// The Compiler does not find it.
// Here you will get an exception at runtime,
// Because obj is of the int type, it is not of the string type.
// OBJ = (string) OBJ + 10;
// If you convert it to an incorrect value type,
// You will also get a runtime exception
// Although there is implicit conversion syntax here.
// OBJ = (double) OBJ + 10;
As you can see, even though OBJ stores an int value, if there is no conversion, the compiler still won't let you perform any mathematical operations. It seems to help you determine whether you actually have an int type, but it is not. You can convert to a completely different type, but the compiler does not check it. The result is that you get a runtime exception.
So you have to execute the display conversion, which is not guaranteed, just because the compiler won't let you run without the conversion.
The new dynamic keyword comes. It tells the compiler not to force Additional rules in yourCode.
DynamicDyn = 10;
Console. writeline (Dyn. GetType ());
// Same as "object.
// Output system. int32 because
// This is the type of the value stored in this object.
// No compilation error because
// The Compiler does not compile
// Try to identify the dynamic object type.
Dyn = Dyn + 10;
// Similarly, this operation is performed in all values or
// Other types that support the "+" operator are successfully computed.
Dyn = 10.0;
Dyn = Dyn + 10;
Dyn = "10 ";
Dyn = Dyn + 10;
This is the main difference between an object and a dynamic-using dynamic is equivalent to telling the compiler that the object type is determined only at runtime and the compiler will not try to intervene. In the end, you can write less code. However, I would like to emphasize that, compared to using the original object keyword, this will not increase any danger. Similarly, it does not reduce any risks. Therefore, it is better to use a dynamic object when any object needs a type check technique (such as reflection.
The following problem usually occurs: "Since a dynamic object can be any object and the compiler does not check what it is, does this mean that you can pass a dynamic object to my trusted method/system and cause it to crash?"
Let's assume we have a simple method.
Public static voidPrint (StringArg)
{
Console. writeline (ARG );
}
Now let's see how you can pass the dynamic object to it.
DynamicDyn = 10;
// You will get an exception here at runtime.
Print (Dyn );
You can see that although the compiler allows you to pass a dynamic object to your method, your method will never get this object if it is a wrong type. An exception has been thrown before the method is actually executed. Only when it contains an appropriate value can you pass the dynamic object to your method, which is of the string type here.
DynamicDyn = "10 ";
Print (Dyn );
Again, this is no more behavioral difference than using the object keyword.
// Not compiled.
// Print (OBJ );
// Compile, but an exception occurs during the running process.
// Print (string) OBJ );
// The code here will work normally, because obj is a string type,
// But you do not need to convert.
OBJ = "10 ";
Print ((String) OBJ );
Someone says (Int) Obj is not hard to understand. Why should we use another dynamic? Well, in some cases, You have to execute many conversion operations, which makes your code hard to understand. In some cases, simple conversions cannot achieve the goal. You need to call the reflection method, such as invokemember or getproperties. A good example is com interoperability, which is why it needs to be modified to use the new dynamic feature (for more information, click "how-").
At the same time, use the dynamic keyword and dynamiC LanguageRuntime makes many previously impossible or hard-to-implement solutions feasible, including interoperability with dynamic languages. I have mentioned these two situations in my previous blog: introducing expandoobject and creating wrappers with dynamicobject.
You may want to go to the msdn walkthrough to see how you can call the ironpython library from C # and Visual Basic. This is a really cool Introduction: Using Dynamic Programming ages to build Scriptable applications, author: Dino viehland. Another good introduction will show some examples and explain the design principles behind this feature: dynamic binding in C #4, author Mads torgersen.
The conclusion is that we don't need to worry that someone will use the dynamic feature to destroy your code. It has no more (and no less) danger than the object keyword.
Therefore, if you often use the object keyword and have to execute a bunch of conversions "and/or" use reflection to call the methods or attributes of the object, you may pay attention to the dynamic keyword. In many cases, it is more convenient than an object and requires less code.
Add chapter for the Translator:
The VaR keyword is not mentioned in the original article. I believe many people will think of VaR at this moment.
VaR is generated in C #3.0 and is defined in msdn: variables declared in the method range can have implicit types of var. Implicit local variables are strongly typed (as if you have declared this type), but the type is determined by the compiler.
When the VaR keyword is used to declare a variable, the compiler determines the type of the Variable Based on the assigned instance type, that is, type inference.
VaRVa = 10;
Console. writeline (va. GetType ());
// Output system. int32 because
// This is the type of the value stored in this object.
// The VA compilation type has been determined by the compiler as Int.
// No compilation error because
// When va assigns a value in the first sentence
// The Compiler determines that its type is int.
Va = va + 10;
// Compilation error because
// The VA variable has been determined to be of the int type, while 10.0 is of the double type,
// And double type cannot be implicitly converted to int type.
// Va = 10.0;
VaR is a strongly typed object;
Compared with dynamic, VAR does not have any dynamic features during runtime. It is only the function of the compiler to reverse infer its type during compilation, which is the same as the function of directly declaring variables with the type during compilation. It is just the syntactic sugar provided by the compiler. Dynamic is not a syntactic sugar. Dynamic needs to be supported during runtime.