Static, dynamic, and dynamic

Source: Internet
Author: User

Static, dynamic, and dynamic

In C #4.0, the core feature is the introduction of dynamic types.

1. Introduction to dynamic types

C # Is a static language, because it must explicitly specify the type of the variable when defining the variable. For example, in code such as int I = 5;, int is the type of variable I. If the type of the variable is not explicitly specified when the variable is defined, the Code cannot be compiled.

In C #4.0, Microsoft introduced the dynamic keyword to define the dynamic type. When we use a variable restricted by the dynamic keyword, the compiler does not know its type. This type can only be determined when the program is running. The following code defines dynamic types:

Dynamic I = 5;

The code above shows that the process of defining a dynamic type is very simple. You only need to change the previous int type to the dynamic keyword.

What are the differences between static and dynamic types? Use code to describe:

Object obj = 10;

Obj = obj + 10; // compilation Error

Dynamic I = 10; // dynamic type definition

I = I + 10;

In the above Code, the first line of obj is of the object type, but the compiler detects that the "+" operator cannot be applied to the object and int types. To compile the code, you must use forced type conversion. The dynamic type definition does not need to be converted. The specific type of the variable defined by the dynamic type can only be determined when the program is running, and the compiler does not know the type, so no compilation error occurs.

 

2. Why does C # introduce dynamic types?

2.1 can reduce the use of forced type conversion

2.2 call dynamic languages such as Python

The dynamic type makes it possible for C # To call a dynamic language like Python. For example:

1 ScriptEngine engine = Python. createEngine (); 2 Console. writeLine ("calling the print function output in Python:"); 3 engine. execute ("print 'Hello world'"); 4 Console. read ();

The preceding Code calls the print function of Python in C # To print messages. To run this code, you must download IronPython. IronPython is a dynamic Language Implemented on. NET Framework.

Because the specific types of dynamic type variables can only be determined at runtime, smart prompts are not useful for dynamic type variables. When using a dynamic type, developers must know exactly the members of the type. Otherwise, it is difficult to find related errors when running the program.

 

3. Dynamic type constraints

The dynamic type must meet the following constraints:

3.1 cannot be used to call extension methods

Dynamic types cannot be used as parameters to call extension methods. For example, the following code may cause compilation errors:

Var numbers = Enumerable. Range (10, 10 );

Dynamic number = 4;

Var error = numbers. Take (number); // compilation error

This error occurs because the extension method is defined in another file. If the parameter is a dynamic type, the compiler cannot determine the specific type of the parameter, because you do not know which source file to import. We can solve this problem in two ways:

The first type is to forcibly convert the dynamic type to the correct type: var right1 = numbers. Take (int) number );

The second method is to call the extension method using static methods: var right2 = Enumerable. Take (numbers, number );

Both methods are possible, but dynamic types are not recommended when calling extension methods.

 

3.2 implicit conversion cannot be performed between the delegate and the dynamic type.

Lambda expressions cannot be defined as dynamic types, because there is no implicit conversion between them, the following code will produce a compilation error:

Dynamic lambdarestrict = x => x + 1; // compilation Error

To define a Lambda expression as a dynamic type, you must specify the delegate type. The specific solution is as follows:

Dynamic rightLambda = (Func <int, int>) (x => x + 1 );

 

3.3 constructors and static methods cannot be called.

Dynamic s = new dynamic (); // compilation error because the compiler cannot specify a specific type at this time.

 

3.4 type declaration and generic type parameters

Dynamic keywords cannot be used for base class declaration, dynamic cannot be used for type parameter constraints, or as part of the interface implemented by the type. The specific instance code is as follows:

1 class DynamicBaseType: dynamic // The base class cannot be dynamic type 2 {3} 4 5 class DynamicTypeConstrain <T> where T: dynamic // The dynamic type cannot be used as the type parameter 6 {7} 8 9 class DynamicInterface: IEnumerable <dynamic> // dynamic cannot be part of the implemented interface 10 {11}

 

4. Implement your own dynamic behavior

After introducing static types, We can dynamically add attributes and methods for types to achieve our own dynamic behavior. Specifically,. NET supports three ways to achieve dynamic behavior:

(1) Use ExpandoObject;

(2) Use DynamicObject;

(3) Implement the IDynamicMetaObjectProvider Interface

 

4.1 Use ExpandoObject for Dynamic Behavior

ExpandoObject is the simplest way to implement dynamic behavior. Its implementation code is as follows:

1 using System; 2 using System. dynamic; 3 4 namespace dynamic type 5 {6 class Program 7 {8 static void Main (string [] args) 9 {10 Dynamic expand = new ExpandoObject (); 11 // dynamically bind member 12 expand. name = "Helius"; 13 expand. age = 24; 14 expand. addmethod = (Func <int, int>) (x => x + 1); 15 // call type member 16 Console. writeLine ($ "enpand type name: {expand. name}, age: {expand. age} "); 17 Console. writeLine ($ "Call the expand Type Dynamic help method: {expand. addmethod (5)} "); 18 Console. readKey (); 19} 20} 21}

The above code dynamically adds attributes and functions for the expand dynamic type by using the ExpandoObject class, And the expand type can also be called successfully.

 

4.2 Use DynamicObject for Dynamic Behavior

In addition to ExpandoObject, we can also rewrite DynamicObject to implement dynamic behavior. The specific implementation code is as follows:

1 using System; 2 using System. dynamic; 3 4 namespace dynamic type 5 {6 class Program 7 {8 static void Main (string [] args) 9 {10 Dynamic dynamicobj = new DynamicType (); 11 dynamicobj. callMethod (); 12 dynamicobj. name = "Helius"; 13 dynamicobj. age = 24; 14 Console. readKey (); 15} 16} 17 18 19 class DynamicType: DynamicObject20 {21 // rewrite the TryXXX method, which dynamically calls 22 public override bool TryInvokeMember (InvokeMemberBinder binder, object [] args, out object result) 23 {24 Console. writeLine ($ "{binder. name} method being called "); 25 result = null; 26 return true; 27} 28 29 public override bool TrySetMember (SetMemberBinder binder, object value) 30 {31 Console. writeLine ($ "{binder. the Name} attribute is set. The value is {value} "); 32 return true; 33} 34} 35}

4.3 Use the IDynamicMetaObjectProvider interface to implement dynamic behavior

Because the Dynamic type dynamically creates objects during running, when accessing each member of this type, the GetMethodObject method is called first to obtain Dynamic objects, then the call is completed through this dynamic object. To implement the IDynamicMetaObjectProvider interface, we need to first implement a GetMetaObject method to return the DynamicMetaObject object.

1 using System; 2 using System. dynamic; 3 using System. linq. expressions; 4 5 namespace dynamic type 6 {7 class Program 8 {9 static void Main (string [] args) 10 {11 12 dynamicicobj2 = new DynamicType2 (); 13 dynamicObj2.Call (); 14 Console. readKey (); 15} 16} 17 18 19 class DynamicType: DynamicObject20 {21 // rewrite the TryXXX method, which dynamically calls 22 public override bool TryInvokeMember (InvokeMemberBinder binder, object [] args, out object result) 23 {24 Console. writeLine ($ "{binder. name} method being called "); 25 result = null; 26 return true; 27} 28 29 public override bool TrySetMember (SetMemberBinder binder, object value) 30 {31 Console. writeLine ($ "{binder. the Name} attribute is set with the value {value} "); 32 return true; 33} 34} 35 36 37 internal class DynamicType2: IDynamicMetaObjectProvider38 {39 public DynamicMetaObject GetMetaObject (Expression parameter) 40 {41 Console. writeLine ("start to get metadata ...... "); 42 return new Metadynamic (parameter, this); 43} 44} 45 46 internal class Metadynamic: DynamicMetaObject47 {48 internal Metadynamic (Expression expression, DynamicType2 value): base (expression, bindingRestrictions. empty, value) 49 {50} 51 52 public override DynamicMetaObject BindInvokeMember (InvokeMemberBinder binder, DynamicMetaObject [] args) 53 {54 // get real object 55 DynamicType2 target = (DynamicType2) base. value; 56 Expression self = Expression. convert (base. expression, typeof (DynamicType2); 57 var restrictions = BindingRestrictions. getInstanceRestriction (self, target); 58 // name of the output binding method 59 Console. writeLine ($ "{binder. name} method called "); 60 return new DynamicMetaObject (self, restrictions); 61} 62} 63}

Result:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.