[Feiqiu] uses C #4 to write dynamic code

Source: Internet
Author: User
Tags visual studio 2010

(1) Use C #4 to write dynamic code

C #4 adds a dynamic keyword, which can be used to compile "dynamic" code.

For example, the following code creates an expandoobject object (which must be defined as dynamic ):

 

Dynamic dynamicobj = new expandoobject ();

 

The uniqueness of this object is that we can add new members to it at any time:

Dynamicobj. value = 100; // Add a field

Dynamicobj. Increment = new action () => dynamicobj. Value ++); // Add Method

 

These dynamically added members share the same usage as common class members:
Instant Messaging Software

 

For (INT I = 0; I <10; I ++)

Dynamicobj. increment (); // call Method

Console. writeline ("dynamicobj. value = {0}", dynamicobj. Value); // Access Field

 

The expandoobject object implements the idictionary <string, Object> interface and can be viewed as a dictionary object. All dynamically added members are elements in this dictionary object. This means that we can not only add new members, you can also remove unnecessary members at any time:

 

// Remove the increment method

(Dynamicobj as idictionary <string, Object>). Remove ("increment ");

 

After the method is removed, attempting to access this method will cause a runtimebinderexception.
(2) Use the dynamic keyword to simplify the code for interacting with COM components

To. net, which calls the COM component in the "hosting world". We must use the "InterOP assembly" as a bridge, the "Interoperability assembly" defines the correspondence between the CLR type and the com type.

Just give. add reference to the "Interoperability assembly" in the. NET project.. NET application to create various types of instances (that is, com package objects) that are contained in this Assembly, call these objects (or access their properties) will be forwarded to the COM component.

Taking word as an example, you may frequently need to write such code before C #4.0:

 

Object wordapp = new word. Application (); // create a word object

Object filename = policmydoc.docx "; // specifies the Word document.

Object argu = system. reflection. Missing. value;

Word. Document Doc = wordapp. Documents. Open (ref filename, ref argu,

Ref argu, ref argu,

Ref argu, ref argu,

Ref argu, ref argu );

 

The above call statement for the open () method can only be described by the word "Terror", because the open () method in the word component defines too many parameters.

C #4 Use the dynamic keyword and use the new syntax features named parameters and optional parameters learned from Visual Basic to write more concise code:

 

Dynamic wordapp = new word. Application ();

Dynamic Doc = wordapp. Documents. Open (filename: Using mydoc.docx ");

 

The preceding Code saves unnecessary parameters and removes the ref keyword before the parameter.

When the above Code is run, DLR will use reflection technology to "bind" dynamic expressions to the word. application proxy objects that are contained in the com interoperability assembly.
(3) C #4 Dynamic Programming Technology insider

Dynamic variables defined in C #4 can reference the following types of objects:

L Traditional "static" CLR objects.

L com package object. We have already discussed this.

L implements the "Dynamic Object" of the idynamicmetaobjectprovider interface. expandoobject is an instance of this type of object.

L objects created by dynamic languages based on DLR (such as ironruby and ironpython.

From the perspective of C # programmers, all four objects are the same and can be referenced by a dynamic variable, while the DLR dynamically "binds" method calls and field access requests to real objects while running the program.

Dynamic functions are supported by DLR and are the result of the division of labor between the C # compiler and DLR.

See the following sample code:

 

Dynamic d = 100;

D ++;

 

C # When the compiler processes the above Code, it does not check whether variable D supports auto-increment operations, instead, a callsite <t> Object (<> P _ Site1) is created for it ):

 

Private Static class <main> o _ sitecontainer0 {

Public static callsite <func <callsite, object, object >><> P _ Site1;

}

 

The callsite <t> is translated as a dynamic (CALL) site by msdn. It is one of the core components in DLR.

Dynamic Site object through callsite <t>. create () method, C # compiler will specify an object (called "Dynamic Site binding object") derived from callsitebinder for it as its parameter.

Dynamic Site binding objects are related to specific languages. For example, ironpython and C # both have their own dynamic site binding objects.

The main task of binding an object to a dynamic site is to convert the dynamic expression in the Code (d ++ in this example) into an abstract syntax tree (AST: abstract syntax tree )", this syntax tree is called "DLR Tree" and is in. net 3.5 is extended based on the LINQ Expression Tree introduced. Therefore, it is sometimes called "Expression Tree )"

The DLR internally calls the compile () method of this expression tree to generate the Il command to obtain a delegate that can be executed by CLR (in this example, its type is func <callsite, object, object> ).

The dynamic call site object (<> P _ Site1 in this example) has a target attribute, which references the delegate that has been made a good life.

After the delegate is generated, the execution of the dynamic expression is embodied in the delegate execution. In fact, the parameter is directly "written to death" by the C # compiler in the Il code.

The simplified code is as follows (obtained through reflector, variable name modified for ease of reading ):

 

Object D = 100;

Object CS $0 $0000 = D;

If (<> P _ Site1 = NULL)

<> P _ Site1 = callsite <func <callsite, object, Object>. Create (......);

D = <> P _ site1.target (<> P _ Site1, CS $0 $0000 );

The above types of inference, method binding, and IL code generation are all completed when the program is running.
(4) is dynamic code slow?

Dynamic Programming Language is easy to learn and use, with compact code and flexible development, but its performance has always been a weakness ". To improve performance, DLR has designed a three-level cache policy.

An object bound to a dynamic site will add corresponding test conditions (called "test") to the syntax tree converted from a dynamic call expression to form a "rule )", this rule can be used to determine whether a syntax tree can be used for a specific dynamic call expression.

For example, see the following dynamic expression:

 

D1 + D2

 

If both D1 and D2 are int integers during the program running, the rules generated by DLR are as follows:

If (d1 is Int & D2 is int) // test condition

Return (INT) d1 + (INT) D2; // syntax tree

 

By checking the "test condition" in the rule, DLR can know whether a dynamic expression can use the syntax tree that the rule contains.

"Rules" are the main objects cached by DLR.

The delegate referenced by the target attribute of the Dynamic Site object described above is the first-level cache, and its processing logic is as follows:

 

// The current processing rule, which belongs to the 1st-level cache

If (d1 is Int & D2 is int) // test condition

Return (INT) d1 + (INT) D2; // if the test conditions are met, an expression tree is directly returned.

// If the cache is not hit, search in the cache of level 2nd and level 3rd. If yes, update the cache of level 1st with the found result.

Return site. Update (site, D1, D2 );

 

If no hit rule is found in the three-level cache, the binding object of the Dynamic Site will try to create a new rule. If the new rule fails to be created, it is determined by the default call site binding object provided by the current programming language (such as C #). The common practice is to throw an exception.

The current version of DLR caches 10 rules at level 2nd and 3rd rules at Level 100.

Because DLR has designed a "rule" cache system and fully utilizes the JIT cache provided by CLR (because all dynamic call code will eventually be converted to Il commands that can be executed by CLR, the CLR can cache the Code), so that the performance of dynamic code is poor only during the first execution, and the performance of subsequent continuous calls can approach static code.
3 C #4 integration with dynamic languages

Since almost all programming languages can be expressed using the abstract syntax tree, in theory, DLR supports unlimited interoperability among multiple programming languages. In the current version, it can implement the interoperability between C #/Visual Basic and ironpython and ironruby. I believe that the DLR implementation of other dynamic programming languages will soon emerge.

One interesting thing is that the current dynamic programming languages based on DLR all start with "iron", such as ironruby and ironpython. Jim hugunin, ironpython designer and DLR architecture designer, once explained at the Microsoft PDC 2008 conference that the main purpose was to avoid a "python. net or Python. net and other "Microsoft-flavored" names have "ironpython ". He stressed that the "Iron" series of dynamic languages will strictly abide by the standards and specifications of the Dynamic Language, respect the historical and accumulation of these dynamic languages, and will not introduce some limitations. the new language features of the. NET platform.. At the same time, Jim hugunin pointed out that the "Iron" series of languages can be well integrated with existing. Net class libraries, programming languages and tools, and can be "embedded" into. Net host programs.
(1) Dynamic Object communication protocol

Since the features of various dynamic programming languages vary greatly, implementing interoperability between languages is a challenge. Therefore, DLR adopts a smart strategy. Instead of trying to design a "general type system" (CLR does this), it designs a "general object communication protocol ", it is required that all dynamic objects requiring interoperability must implement the idynamicmetaobjectprovider interface. This interface defines a getmetaobject () method, receives a syntax tree object as a parameter, and returns a "dynamic metadata (dynamicmetaobject)" to the outside world) "object:

 

Dynamicmetaobject getmetaobject (expression parameter );

 

The dynamicmetaobject object provides two important attributes: Restrictions references a set of test conditions, and the expression attribute references a syntax tree. The combination of these two attributes is the "rule" that can be cached by Dynamic Site objects )".

After the Dynamic Site binding object (callsitebinder) in the DLR obtains the dynamicmetaobject object, it calls the methods provided by this object to create the "rule ", let the target attribute of the "Dynamic Site object (callsite <t>)" reference it to complete dynamic binding.
(2) Dynamic Language integration environment

To facilitate the integration of static programming languages and various dynamic programming languages, DLR provides a complete set of components called common hosting, including scriptruntime and scriptscope.

The following uses ironpython as an example to describe how to integrate dynamic programming language code in a program developed in C #4.

First, you must create a scriptruntime object, which is a top-level object used to "embed" the runtime environment of a specific dynamic language in A. NET application domain:

 

Scriptruntime pythonruntime = python. createruntime ();

 

Next, you need to create a scriptengine object, which is the execution engine of Dynamic Language code:

 

Scriptengine engine = pythonruntime. getengine ("py ");

 

The scriptscope object is similar to the namespace in C #. Some variables can be defined to input data to dynamic code. For example, the following code passes an expandoobject object created in C # To the Python code:

 

Scriptscope scope = pythonruntime. createlist ();

// C # create a dynamic object

Dynamic expando = new expandoobject ();

Expando. Name = "jinxuliang"; // Add a field dynamically.

// Enable ironpython to receive the expando object created by C #

Scope. setvariable ("expandoobject", expando );

String pythoncode = "Print expandoobject. Name ";

// The ironpython engine executes Python statements.

Engine. createscriptsourcefromstring (pythoncode). Execute (scope );

 

The above sample code is to directly execute Python code. In actual development, it is more common to directly execute the code in the python file. Suppose there is a calculator. py file, which defines an add function:

 

Def add (A, B ):

Return A + B

 

The following C # code can be directly executed:

 

Scriptruntime pythonruntime = python. createruntime ();

Dynamic pythonfile = pythonruntime. usefile ("Calculator. py ");

Console. writeline (pythonfile. Add (100,200 ));

 

The above example shows that, with the support of DLR, static programming languages can use libraries developed by dynamic languages. In turn, dynamic programming languages based on DLR can also use libraries designed for static languages, for example, standard. net base class library.

This means two points:

(1) Now we can combine "static" and "dynamic" programming languages to develop highly interactive applications and build a system framework using static programming languages, using Dynamic Programming Languages to achieve interactivity is a very noteworthy application field.

(2) In the future, there will be libraries that are applicable to "static" and "dynamic" programming languages, and a step forward towards achieving "Ubiquitous reuse.

Visual Studio 2010 is the new. NET Programming Language F # provides a dedicated project template, but does not support development of dynamic languages such as ironpython and ironruby. and later versions of Visual Studio directly support dynamic language development.

 

 

 

Follow the technical Article Fei Qiu: http://www.freeeim.com/, 24 hours professional transfer.

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.