Programming for the New Platform Based on New Platform Program Design Jeffrey Richtertranslator: BIN Yang (Arec Pink Team) In the past years, I have been paying attention to Microsoft .NET General Language Runtime platform. I think most new development will be concentrated on this platform because it makes the program easier and more convenient. I also hope that the current application development will be transferred to this platform as soon as possible. In order to help developers understand this new platform, the following chapters introduce a variety of different programming methods on .NET. I assume that you have been very familiar with object-oriented programming concept. Each chapter will focus on general programming topics for general language running. All .NET developers must understand these topics. In order to indicate some examples of code, I must choose a programming that supports .NET universal language running. Originally selectable, the most universal language should be compilation of intermediate language (Intermediate Language). However, the use of IL assembly is not common, so I decided to use C #. C # is a new language for Microsoft designed for Managed Code development. Here, although the code sample in the article is written in C #, the comment is also a coding method for C #, but the concept we discussed is for a generic language, so these concepts can be applied to any .NET platform. I will introduce a variety of program design themes and tell you how they are implemented. As for the detailed description of each subject and all the details around the subject are not my purpose. If you need to understand the detailed content of any programming topic, please refer to the General Language Run and Language documentation. Now we have specifically introduced. The true object-oriented design is implemented for programmers using Win32 (R) SDK, most of the visiting operating system is implemented through the DLL exported independent function. If you use a non-directional language, such as C, you will be very easy to call these independent functions, but let the developers who have no experience go face thousands, the surface does not seem to contact the function, which will make They are very confused. What makes problems more difficult is the fact that many functions are headed (for example, getCurrentProcess and getStockObject). In addition, Win32API has developed, Microsoft has added new functions, they have previously Compared to the semantics, there are some subtle different characteristics. Usually you can identify these new functions because their names are very similar to the early function name (icon CreateWindow / CreateTYPELIB2, and my personal very favorite function: createpen / createpenIndirect / extCreatepen). All of these issues give program developers an impression, which is difficult to develop Windows (R) on the .NET platform. Microsoft listened to the requirements of the developer and established a full-scale platform. The platform service can now be divided into independent namespaces. (For example, System.Collections, System.Data, System.IO, System.Security, System.Web, etc.), each namespace contains a series of associated classes that allow access to platform services. Since the method of class can be reused, those that are similar to those in function can use the same name, which are distinguished by their respective prototypes. For example, a class can provide three different versions of Createpen methods. All methods achieve the same function: create a brush object. However, the parameters used for each method are different, and there is a small difference in function.
In the future, if Microsoft needs to create a fourth Createpen method, this new approach will be as seamless as a first-class resident. Since all platform services are provided through such object-oriented examples, software developers should understand the object-oriented programming. This object-oriented example can also be applied to other functions. For example, use inheritance and polymorphism, create a special version of the base library type, which will become very easy. I strongly recommend that you are familiar with these concepts because they are very important for the work under Microsoft .NET framework. System.Object In .NET, all objects are inherited from System.Object. This means that the following two types of definitions are consistent: (represented by C #) Class Jeff} andclass jeff: system.Object {???} Since all object types are inherited in System.Object, every Each object of the type ensures a certain maximum functionality. The available public methods for class System.Object are listed in Figure 1. Figure 1 System.Object Public MethodSmethod
Description
Equals
This Virtual Method Returns True If Two Objects Have The Same Value. Almost Every Type Should Override This Method. For More Information About this, See The section Casting Between Data Types.
Gethashcode
This virtual method returns a hash code for this object's value. A type should override this method if its objects are to be used as a key in a hashtable. The method should provide a good distribution for its objects.
Gettype
This is the Type.
Tostring
.
Universal Language Run requires all object instances to create (it calls newobj IL instructions). The following code shows how to create an instance of a JEFF type (this type is defined in front) JEFF J = New Jeff ("constructorparam1"); New operator is assigned to the specified type on the system-managed pile (Managed HEAP) Bytes are created. It initializes the main members of the object. Each object also has some additional byte space, which is a universal language run (CLR) to manage objects. For example, the virtual table pointer of the object and a reference for the synchronization block. During the specific process of calling New, the constructor of the class is called, and the specified parameter is passed to the class constructor, and the parameters transmitted in the previous code are "constructorparam1"). Note that most languages should compile constructors so they can call the constructor of the base class. However, there is no need to do this in a general language operation. After the New operator completed all the operations I mentioned in front, it returned a reference to the newly created object. In the above code sample, this reference is saved in the variable j, and the type J is jeff. By the way, the New operator has no anti-operator, that is, there is no way to explicitly release or destroy this created object. General Language Run provides a Garbage-Collected environment that monitors objects that never use or access, and automatically releases these objects. In this regard, I will introduce in MSDN (R) Magazine that will be issued. The conversion of data types is a very common operation of converting an object from one data type to another. In this section, I will introduce some rules for the data type conversion of the object. Now we start from the following line of code: System.Object O = New Jeff ("constructorparam1"); the above code can be compiled and executed correctly because there is an implicit type conversion. The New operator returns a JEFF type reference, and o is a reference to the System.Object type. Since all types (including Jeff type) can be converted to System.Object, this implicit type conversion is successful. However, if you do one line below, you will get a compilation error because the compiler does not provide a conversion implicitly converted from the base type to the export type. Jeff J = O; you must join a mandatory type conversion: Jeff J = (Jeff) O; now the code can be successfully compiled and executed. Let's look at another example: system.object o = new system.object (); jeff j = (jeff) o; in the first line, I created a SYSTEM.OBJECT type object. In the second row code, I tried to convert a reference to a system.object type into a JEFF type reference. There is no problem with the two lines of code compilation. However, when executed, the second line of code produces an exception (Exception), if this exception is not processed, the program will abort the exit. When the second row code is executed, the general language run determines whether the object type of the O reference is an object of a Jeff type (or any Jeff type export type). If so, the general language runs allows type conversion; however, if o The object type of reference is non-relationship with Jeff, or reference to the JEFF base class, and the general language run will prevent this unsafe conversion and generate an InvalidCastException exception error.
C # provides another way -as operator-to implement data type conversion: jeff j = new jeff (); // Create a new Jeff object system.object o = j as system.object; // will j Converting to Object Type // O Now reference is that the object JeffaS operator converts an object into a specified type. However, different from normal data type conversion, the AS operator will not produce an exception error. Instead, if the data type cannot be successfully converted, the result will be NULL. When using the wrong type conversion result, a NullReferenceException exception error is generated. The following code proves this concept. System.Object o = new system.object (); // Create a new Object object jeff j = o as jeff; // converts o converts O object // Conversion failure: no exception error, but J For null .j.toString (); // The access to J generates a NullReferenceException exception error In addition to the AS operator, the C # also provides an IS operator. The IS operator checks if the object instance is consistent with the data type of å, and its result is False or TRUE. The IS operator does not produce an abnormal error. System.Object o = new system.object (); system.boolean b1 = (o is system.object); // b1 value is TRUESYSTEM.BOOLEAN B2 = (o is jeff); // b2 value is false If the referenced object is empty, the IS operator always returns FALSE because there is no object to check its type. In order to be confident that you have understood these content, assume that the definitions of the following two classes are present. Class b {int x;} Class D: b {int x;} Now checking Figure 2, see which code lines can successfully compile and execute (ES), which will cause compilation errors (CE), which will cause universal language Run error (RE). Figure 2 Data Type Casting ResultsStatement
ES
CE
RE
System.Object O1 = new system.Object ();
Y
N
N
System.Object O2 = new b ();
Y
N
N
System.Object O3 = New d ();
Y
N
N
System.Object O4 = O3;
Y
N
N
B b1 = new b ();
Y
N
N
B b2 = new d ();
Y
N
N
D D1 = New D ();
Y
N
N
B b3 = new system.Object ();
N
Y
N
D D1 = new system.Object ();
N
Y
N
B B3 = D1;
Y
N
N
D D2 = B2;
N
Y
N
D D4 = (d) D1;
Y
N
N
D D5 = (d) b2;
Y
N
N
D D6 = (d) B1;
N
N
Y
B b4 = (b) O1;
N
N
Y
B b5 = (d) b2;
Y
N
N
A collection and namespace (Assembly and namespaces) A series of types can form an Assembly (a set of files) and published. In a collection (Assembly), there are different namespaces. For developers, namespace look like a logical combination of related types. For example, the base library collection includes a lot of namespaces. System namespace includes some core underlying types, such as Object, Byte, Int32, Exception, Math, and Delegate, and more. The system.collection namespace contains these types: ArrayList, BitArray, Queue, and Stack. For compilers, namespace is just a simple way to ensure that the type name is unique, which is implemented by a point-separated identity symbol, which also makes the type name longer. For the compiler, the type Object in the system namespace is actually a system.object type. Similarly, the type Queue in the System.Collection namespace is actually a System.Collections.Queue type. The running engine does not know about the namespace. When you visit a type, generic language runs only need to understand the full name of this type and which collection contains this type of definition, so that the general language runs to load the correct collection, find this type, and operate. Programmers usually want the most accurate way to represent their algorithm; use the full name of the type to reference each class is very inconvenient. For this reason, many program development languages provide a statement that tells the compiler to add a variety of prefix before the type name until the match is completed. When using C # encoding, I usually put the line below in my source code module: use system; When I reference a type in my code, the compiler needs to be confident that the type is defined, and my code This type is accessed in the correct way. If the compiler cannot find the type according to the specified name, it adds "System" before the type name, and then check whether the generated name matches the existing type. The front code line allows us to use "Object" in your code, the compiler will automatically extend the name to System.Object. When checking the type definition, the compiler needs to know which collection contains this type, so that collect information and type information can be posted into the result file. To get collection information, you must pass the collection of reference types to the compiler. You may think that this solution will have some potential problems. For the convenience of program development, you should avoid creating a type with conflict names. However, in some cases, this is almost impossible. .NET encourages the reuse of components. Your program may also use Microsoft's components that Microsoft created and other components created by my company. The components of these companies may all provide a type called Foobar --------- Microsoft's FOOBAR implementation, and the functionality of Richer's FOOBAR is completely different. In this case, you don't have the type of naming control. To quote Microsoft's FOOBAR, you have to use Microsoft.foobar. If you want to quote our foobar, you should use Richter.foobar. In the following code, it is uncertain to FOOBAR. If the compiler is wrong here, it is not bad, but in fact the C # compiler is a possible FOOBAR type, you only find problems when running: USING Microsoft; USING RICHTER; class myapp {Method Void Hi () {FOOBAR F = New Foobar (); // Uncertain, the compiler selection a possible FOOBAR type}} In order to avoid this uncertain reference, you must clearly tell the compiler that you want to create which type of FOOBAR.