C # Programming language future function

zhaozj2021-02-08  269

C # Programming language future function

Prashant Sridharanmicrosoft Corporation For: Microsoft® Visual C # (TM) Summary: Microsoft Corporation is developing the next major version of the C # language. This article describes four main new features, namely, generic, iterative procedures, anonymous methods, and local types. table of Contents

Introduction Pan Iterative Procedure Anonymous Method Local Type Compliance Suitability More Information Introduction C # is an innovative new programming language, which is subtly combined with the most commonly used industry language and research languages. While maintaining C # design, Microsoft has introduced several potential new features in C # language, enhances the efficiency of developers in language construction. Microsoft C # Since its inception in February 2001, many developers have begun to build software using C # programming languages. Microsoft itself also uses C # to build several formal applications, including .NET Framework, MSN web properties, and Tablet PC SDK. This shows that C # is a language suitable for constructing high quality business software. Many of the features in the C # language are created based on the following four different design goals:

Unified Type Systems and Simplified Types and Reference Types in C # Language. Establish component-based design by XML annotations, features, attributes, events, and entrustments. Establish a practical developer control feature with a unique feature of C # languages ​​(including security pointer, overflow checking, etc.). Establish a practical language constructor such as Foreach and USING statements to improve the efficiency of developers. In the "Visual Studio for Yukon" version of the C # language, the Microsoft Plan establishes a simple, practical grammar by combining a wide range of research languages ​​and industry languages. These language features include generic, iterative procedures, anonymous methods, and local types. Potential future features In fact, the future innovation function of C # is based primarily on unified type of system, based on component development, developer control functions, and practical language constructs. The following summarizes the four main new features provided in the next major version of the C # language. These features have not been completed, and Microsoft Corporation welcomes the majority of developers to comment on these functions. Pansets become more complex as projects, programmers are increasingly requires a way to better reuse and customize their existing component-based software. In order to achieve advanced code in other languages, programmers typically use a function called "generic". C # will include a safe and efficient generic, which is slightly different from the generic in the template and Java language in C , but there is a big difference in implementation. Generating the latest generic class using the current C #, programmers can create a limited form of real generics by storing data in instances of basic object types. Since each object in C # is inherited from the basic object type, plus a unified .NET type system packaging and unpacking function, programmers can store the reference type and value type to the object type variable. However, there are some performance defects for the transition between the reference type, the value type and the basic object type. To illustrate this, the following code example creates a simple STACK type with two operations "Push" and "POP". The Stack class stores its data in an array of object types, and the PUSH and POP methods are accepted and returned using basic object types: Public Class Stack

{

Private Object [] items = new object [100];

Public void Push (Object Data)

{

...

}

Public Object Pop ()

{

...

}

} Then you can press the custom type (such as a Customer Type) into the stack. However, if the program needs to retrieve data, it is necessary to explicitly convert the result of the POP method to the Customer type. Stack s = new stack (); s.push (new customer ());

Customer C = (Customer) S.POP (); In the internal data structure. Similarly, if the program is to retrieve a value type (for example, an integer) from the stack, you need to explicitly convert the object type obtained from the POP method. This process is called unpacking: stack s = new stack ();

S.push (3);

INT i = (int) S.POP (); Value type and reference type of packing and unpacking operations are very heavy. Moreover, in the current implementation, the type of data placed in the stack cannot be restricted. In fact, you can create a stack first, then press the Customer type into the stack. Then, you can use the same stack and attempt to pop up the data, then convert it to other types, as shown in the following example: stack s = new stack ();

S.Push (New Customer ());

Employee E = (EMPLOYEE) S.POP (); Although the last code sample is incorrectly used, it should be considered an error, but it is actually a legal code, which is not compiled. problem appear. But at runtime, the program will fail due to invalid conversion operation. Creating and using generics using generics in C # can create a high-efficiency data structure for compilers based on their types. After creating these so-called parameterized types, the internal algorithm remains unchanged, but the type of internal data can be changed as the final user settings. In order to help developers save the time of learning this language, the C # general declaration method is substantially the same as C . Programmers can create classes and structures according to the usual method and specify the type parameters using the angle marks (). When using a class, you must replace each parameter with the actual type provided by the user of this class. The following example will create a Stack class that specifies and declares a type parameter named ItemType in the sharp brackets after this class declaration. An instance of a generic Stack class will accept the type created and store this type of data locally instead of converting between the type of creation with the basic object type. Type Parameter ItemType acts as a proxy until the type is specified in the instantiation and uses it as the type of internal item (ie, the parameter type of the PUSH method and the return type of the POP method): Public Class Stack

{

Private itemtype [] items;

Public void Push (ItemType Data)

{

...

}

Public ITEMTYPE POP ()

{

...

}

} When the program uses the Stack class as follows, you can specify the actual type of generic class. This example uses the sharp bracket mark in the instantiation statement to specify the original integer type as a parameter, indicating that the Stack class uses this type: stack stack = new stack ();

STACK.PUSH (3);

INT x = stack.pop (); When this is performed, the program will create a new instance of the Stack class, each of which is replaced by the integer parameters provided. In fact, when the program creates a new instance of the Stack class with an integer parameter, the item array of local storage inside the Stack class will be an integer, not an object. The program also eliminates the problem of packing issues associated with integers into the stack. In addition, when the program comes out of the project from the stack, you don't have to explicitly convert it to the appropriate type, because the current specific instance of the Stack class stores the integer in its data structure. If you want the program to store other types of items in the Stack class, you must create a new instance of a Stack class and specify the new type as a parameter. Suppose there is a simple Customer type, I hope the program uses the Stack object to store this type. To implement this, just instantiate the Stack class and use the Customer object as its type parameters, you can repeat the program code: Stack Stack = New Stack (); stack.push (new customer () );

Customer c = stack.pop (); of course, if the program creates a STACK class that uses the Customer type as a parameter, you can only store the Customer type in the stack. In fact, generics in C # have stringent types, which means that you cannot store integers in the stack, as shown in the following example: Stack Stack = New Stack ();

Stack.push (New Customer ());

STACK.PUSH (3) // Compile time error

Customer C = stack.pop (); // does not require type conversion. The advantage of generics uses generics, programmers only need to write, test, and deploy the code, you can reuse the code for a variety of different data types. The first STACK example has this feature, and the second STACK example allows the program to reuse the code that has little impact on its application performance. For value types, the first Stack example has a large performance problem, and the second STACK example completely eliminates this problem because it removes the box and down type conversion. Moreover, generics will also be checked when compiling. This type parameter can only be the type specified in the class definition when the program is instantiated using the type parameters provided. For example, if the program creates a STACK of a Customer object type, it is not possible to press the integer into the stack. By enforcing this operation, a more reliable code can be generated. In addition, the generic C # implementation reduces the expansion speed of the code than other strict types. Using generic creation with types of collections, you can avoid creating specific variants of each class while maintaining operational performance advantages. For example, a program can create a parameterized Stack class without having to create an IntegersTack for storing an integer, a stringstack for storing strings, and a CustomersTack for storing Customer types. This can increase the readability of the code. Simply create a Stack class, the program can package all the operations associated with a stack in a convenient class. Then, when creating a Customer type, although the Customer type is stored, it is obvious that the program is still the stack data structure. Multiple types of parameters can use any multiple parameter types. Only one type is used in the STACK example. Suppose you have created a simple Dictionary class that stored values ​​and keys. Define a generic version of Dictionary class by declaring two parameters (placed in a comma-defined angle bracket): public class Dictionary {

Public Void Add (KeyType Key, Valtype Val)

{

...

}

Public ValType this [keytype key]

{

...

}

} When using this Dictionary class, you need to provide multiple comma-separated parameters in the angle of the illustrative statements, and provide the correct type of parameters for the add function and the index generator: Dictionary DICT = New Dictionary < Int, Customer> ();

Dict.Add (3, New Customer ());

Customer C = Dict.get [3]; constraints usually, the program is not limited to storing data according to a given type parameter, but often requires a member of the type parameter to perform the statement in a program generic. Why do I need to constrain assumptions in the Add method of the Dictionary class, you need to compare items using the COMPARETO method of the supplied key, for example: public class Dictionary

{

Public Void Add (KeyType Key, Valtype Val)

{

...

Switch (key.compareto (x))

{

}

...

}

} Unfortunately, as expected, the type parameter keyType is a genericity when compiling. If you write this, the compiler assumes that the key instance for the type parameter is KeyType can only perform an operation suitable for basic object types (such as toString). As a result, the compiler will display compilation errors because the CompareTo method is not defined. However, the program can convert the Key variable to an object containing the CompareTo method, such as the IComparable interface. In the following example, the program explicitly converts the instance key of the keyType parameter type to the program that can be compiled: public class Dictionary {

Public Void Add (KeyType Key, Valtype Val)

{

...

Switch ((iComparable) key) .compareto (x))

{

}

...

}

} However, if the Dictionary class is immediately instantiated and the type parameter provided does not implement the IComparable interface, the program will encounter runtime errors, especially the InvalidCastException exception. Declaration Constraints In C #, the program can provide an optional constraint list for each type parameter declared in the generic class. Constraints indicate that a type configured to meet the requirements of generics. You can use the WHERE keyword declaration constraint. He follows the "parameter-requirements" pair, where "parameters" must be a parameter defined in the generic, "Requirements" must be class or interface. To meet the needs of using the CompareTo method in the Dictionary class, the program can add constraints to the keyType type parameter, requiring any type of pass to the Dictionary class as the first parameter, must implement the IComparable interface, for example: public class Dictionary Where keytype: iComparable

{

Public Void Add (KeyType Key, Valtype Val)

{

...

Switch (key.compareto (x))

{

}

...

}

} This will check the code when compiling the code to ensure that the ICOMPARABLE interface is implemented as the type of the first parameter each time you use the Dictionary class. In addition, the program does not need to explicitly convert the variable to the IComparable interface before calling the CompareTo method. Multi-constraints For any given type parameters, the program can specify any multiple interface constraints, but only one class constraint can be specified. Each new constraint is declared in the form of another "parameter-required" pair, and each constraint for a given generic is separated by commas. The Dictionary class in the following example contains two parameters, keytype, and valtype. KeyType type parameters have two interface constraints, and the Valtype type parameters have a class constraint: public class Dictionary Where

KeyType: iComparable,

KeyType: Ienumerable,

Valtype: Customer

{

Public Void Add (KeyType Key, Valtype Val)

{

...

Switch (key.compareto (x))

{

}

...

}

} There is little difference between the compilation method of the generic generic class at runtime. In fact, the compilation result is only the metadata and intermediate language (IL). Of course, in order to accept the type provided in the code, IL should be parameterized. Depending on the type of parameters, the value type is also a reference type, and the generic IL's use of the Fa will vary. When the value of the value is first constructed for the first time, a dedicated generic will be created using the respective positions of the supplied parameters to replace the IL. For each unique value type used as a parameter, a dedicated generic will be created one-time. For example, suppose the program code declares a Stack: Stack Stack; at this time, a dedicated STACK class will be generated, and the corresponding parameters of this class are replaced with an integer. Now, whether the program code is used to use an integer STACK, the generated special STACK class will be repeated. The following example will create two instances of the integer stack, each of which is created using the code generated by this integer STACK runtime: stack stackne = new stack ();

Stack stacktwo = new stack (); however, if a Stack class is created in other locations in the program code, use different value types (such as long integer or user-defined structures) as it The parameters are running, and other forms of generics will be generated, and the long integer parameters in the IL corresponding position will be replaced. The advantage of generic creation dedicated classes constructed for use value is to achieve better performance. After all, each dedicated generic class is "local" contains value type, so it is no longer necessary to convert. The generic work mode is slightly different from the reference type. For the first time, use any reference type to construct a generic, running with an object reference to replace the parameters in the IL to create a dedicated generic. Thereafter, whenever the reference type is used as the type of configuration, it is repeatedly used for the previously created special generics regardless of the type of construct. For example, suppose there are two reference types, Customer classes, and ORDER classes, and further assume that you create a Customer type Stack: Stack Customers; at this time, the dedicated Stack class will generate a dedicated Stack class, which does not store data. Instead, store the subsequently filled object reference. Suppose the next line of code creates a Stack for other reference types, called Order: Stack Orders = New Stack (); Different from the value type, no other dedicated Stack class for the Order type, but Create an instance of a dedicated STACK class and set the Orders variable to reference it. For each object reference for the replacement type parameter, allocate the memory space according to the size of the Order type, and set the pointer to reference the memory location. Suppose you have encountered a line of STACK for creating a Customer type: Customers = New Stack (); The included pointer is set to reference the Customer type size memory area. Since there is a lot of differences in the number of reference types, the general C # implementation of generic C # implementation is greatly reduced by the number of special classes created by the quantity of the reference type to the quotation type of generic class. Expansive speed. In addition, when using type parameters (whether it is a value type or reference type) instantizes generic C # classes, the reflection and actual types can be used in runtime, and their type parameters can be determined. There is a significant difference between the difference between C templates and C # generics between C # generics and other implementations. The C # generic is compiled into IL, which makes it intelligently creates a corresponding private type for each value type at runtime, and the reference type will only create a dedicated type; C template is actually a code extension macro, it is provided Generate a dedicated type for each type of parameters of the template. Therefore, when the C compiler encounters a template (such as an integer STACK), it extends the template code to the Stack class and includes an integer as the type of this class itself. Regardless of the type parameter is the value type or the reference type, if not specifically designed to reduce the code expansion speed, the C compiler will create a dedicated class each time, resulting in more significant code expansion than using C # generics. Moreover, the C template cannot be defined. The C template can only be implicitly defined by using a member (possibly it may not belong to the type parameters).

If the member is presented to the type parameters of the generic class, the program will run normally. Otherwise, the program will fail and may return hidden error messages. Since the C # generics can declare constraints and have strict types, there is no such potential errors. Now, Sun Microsystems® has added other generics in the new version of Java language (code name "Tiger"). The implementation of Sun Selection does not need to modify the Java virtual machine. Therefore, SUN faces how to achieve generic issues on an unmodified virtual machine. The proposed Java implementation uses a generic syntax in templates and C # in C , including type parameters and constraints. However, since it is different from the type of value and processing reference type, the unmodified Java virtual machine does not support value type generics. Therefore, generics in Java cannot be effectively implemented. In fact, the Java compiler will insert automatic down type conversion from the specified constraint (if declared) or the basic object type (if not declared) when you need to return data. In addition, the Java compiler will generate a dedicated type at runtime and then use it to instantiate any constructive type. Finally, since the Java virtual machine itself does not support generics, the type parameters of generic instances cannot be determined at runtime, and other uses reflected will also be severely limited. The generic support of other languages ​​support Microsoft is to support use and create generics in Visual J # (TM), Visual C , and Visual Basic. Although there are time for this functionality to achieve this function, all three languages ​​of Microsoft will contain generic support. At the same time, the C # group is working hard to join the corresponding function in generic basics, laying the foundation for multilingual support. Microsoft is closely collaborated with third-party language partners to ensure that generics are created and used in .NET-based language. Iterative Program Iterative Programs are languages ​​constructed based on similar functions in research languages ​​(such as CLU, SATHER, and ICON). Simply put, through iterative procedures, the type can easily declare the foreach statement to iterate the elements. Why do I need iterative programs now, if the class needs to support iterative operations, they must implement "Enumerator Mode". For example, the compiler extends the Foreach loop structure on the left to the While loop structure on the right: List list = ...

Foreach (Object Obj IN LIST)

{

DOSMETHING (OBJ);

}

ENUMERATOR E = List.GeteNumerator ();

While (E.MOVENEXT ())

{

Object obj = E.current;

DOSMETHING (OBJ);

It is worth noting that in order to make the Foreach loop can run normally, the List data structure (an iterative instance) must support the GetEnumerator function. Once you have created a List data structure, you must implement the getEnumerator function to return the Listenumerator object: Public Class List

{

INTERNAL OBJECT [] Elements;

INTERNAL INT COUNT;

Public Listenumerator GeTenumerator ()

{

Return New Listenumerator (this);

}

} The resulting Listenumerator object must not only implement the current attribute and the MoveNext method, but also maintain its internal state so that the program can be moved to the next item each time the cycle. This internal state machine is relatively simple for the List data structure, but for data structures (such as a binary tree) that require recursive cycles, the state machine will be quite complicated. Since it is required to implement this envelope mode requires a large number of energy and writing a large number of code, C # contains a new structure so that the class can easily indicate that the Foreach loop is an iteration of its content. Defining iterative procedures Since iterative procedure is a logical counterpart for the Foreach loop structure, its definition method is similar to a function: use the foreach keyword and has a pair of parentheses. In the following example, the program will declare an iteration program for the List type. The return type of the iterative program is determined by the user, but because the object type is stored inside the list class, the return type of the following iterative program example is object: public class list {

INTERNAL OBJECT [] Elements;

INTERNAL INT COUNT;

Public Object Foreach ()

{

}

} It is worth noting that after the enumerator mode is implemented, the program needs to maintain internal state machines to track the position of the program in the data structure. The iterative program has a built-in state machine. Using a new Yield keyword, the program can return the value to the Foreach statement called the iterative program. When the iteration program is written next time, call the iteration program, the iterative program will be executed at the position where the last Yield statement is stopped. In the following example, the program will generate three string types: Public Class List

{

INTERNAL OBJECT [] Elements;

INTERNAL INT COUNT;

Public string foreach ()

{

Yield "Microsoft";

Yield "Corporation";

Yield "developer Division";

}

} In the following example, the Foreach loop called this iteration program will be executed three times, and each time you receive the string in the order specified in the first three yield statements: list list = new list ();

FOREACH (String S in List)

{

Console.WriteLine (s);

} If you want the program to implement an iterative program to traverse the element in the list, you need to use the Foreach loop to modify this iterative program makes it traversed by the elements, and generates each item in an array in each iteration: Public Class List

{

INTERNAL OBJECT [] Elements;

INTERNAL INT COUNT;

Public Object Foreach ()

{

Foreach (Object O in Elements)

{

Yield O;

}

}

} The working principle of the iterative program is an iterative program represents the daily operation of the enumerator mode on behalf of the program. The C # compiler converts the code written in the iterative program into the corresponding classes and code that uses the enumerator mode without having to create classes and build state machines. In this way, iterative procedures significantly improved the work efficiency of developers. An anonymous method Anonymous method is another practical language structure that enables programmers to create a package in the delegate and can be executed later. They are based on language concepts called λ functions and similar to the corresponding language concepts in Lisp and Python. Creating a delegate code is an object of a reference method. When you call the commission, the method it is called. The following example illustrates a simple form that contains three controls of the list box, text box, and buttons. When the initialization button, the program will indicate the AddClick method stored in other locations in the object. In the AddClick method, the value of the text box is stored in the list box. This method will be called each time you click this button because the AddClick method is added to the Click delegation of the button instance. PUBLIC CLASS MyForm {

Listbox listbox;

TextBox textbox;

Button button;

Public myform ()

{

Listbox = new listbox (...);

Textbox = new textbox (...);

Button = new button (...);

Button.Click = New EventHandler (AddClick);

}

Void AddClick (Object Sender, Eventargs E)

{

Listbox.tems.add (TextBox.text);

}

} One example using anonymous method is very intuitive. A single function is created and a delegate reference is a program, and each program calls the function whenever this delegate is called. In this function, a series of executable steps are performed. With an anonymous methods, the program does not need to create a new method for this class, and can directly reference the executable steps included in the commission. The declaration method of anonymous method is to instantiate a delegate, and then add a pair of curly brackets that represent the scope after instantiation, and finally add a semicolon for termination statements. In the following example, the program modifies the delegate to create a statement to directly modify the list box instead of the reference representative program to modify the function of the list box. The purpose of the storage code is to modify the list box in the execution scope after the delegate creation statement. Public Class MyForm

{

Listbox listbox;

TextBox textbox;

Button button;

Public myform ()

{

Listbox = new listbox (...);

Textbox = new textbox (...);

Button = new button (...);

Button.click = New EventHandler (Sender, E)

{

Listbox.tems.add (TextBox.text);

}

}

} Please note how the code in the "Anonymous" method is how to access and process variables declared other than its execution range. In fact, anonymous methods can reference variables declared by classes and parameters, and the local variables declared by the method can also be referenced. Transferring parameters to anonymous methods Yes, "anonymous" method statements contain two parameters, namely Sender and E. Check the definition of the Button Class's Click Delegate, you will find that any function of the delegate reference must contain two parameters, the first parameter is an object type, and the second parameter is Eventargs type. In the first example, the program does not use an "anonymous" method, but to the AddClick method, two parameters are passed, and the types are objects and Eventargs, respectively. Even with this code in the inner line, the commission must still receive two parameters. In the "Anonymous" method, you must declare the name of the two parameters, so that the associated code block must use them. When the Click event on the button is triggered, the "anonymous" method is called and the corresponding parameters are passed to the method. When the working principle of an anonymous method encounters "anonymous", the C # compiler will automatically convert the code within the unique named class to the unique name function in the unique name class. The delegation of the storage code block will then be set to reference the objects and methods generated by the compiler. When the delegate is called, the "anonymous" method will be performed by the method generated by the compiler. Local Type Although all source code for maintenance types in a single file is a good way to program object-oriented programming, sometimes performance constraints make the type becomes large. In addition, the overhead of the type split into a subtype is unacceptable in some cases. Moreover, programmers often create or use applications to publish source code and modify results code. Unfortunately, all existing source code modifications will be overwritten when the source code is released again. The local type allows you to split the type of a large source code into multiple different source files to facilitate development and maintenance. In addition, local types can be used to separate the types of the computer generated from the type portion written by the user, making it easier to supplement or modify the code generated by the tool. In the following example, both C # code file file1.cs and file2.cs define classes called FOO. If the local type is not used, the compilation error will occur because the two classes exist in the same namespace. With Partial keywords, you can indicate the compiler: Other definitions that may contain this class. File1.csfile2.cspublic Partial Class Foo

{

Public void myfunction ()

{

/ / Perform operation here

}

}

Public Partial Class foo

{

Public void myotherfunction ()

{

/ / Perform operation here

}

}

转载请注明原文地址:https://www.9cbs.com/read-1193.html

New Post(0)