Special types of members in .NET ---- Microsoft .NET platform series of three translations / Zhao Xiangning in the previous two articles, we studied the basic knowledge of types. This article we will investigate certain special members defined by the type. These types helps object-oriented design in the grammatics required by vigorously simplifying the processing type and its object instance. Type Constructor You are already familiar with what constructor is responsible for the initialization of object instance status. In addition to the instance constructor, Microsoft (R) .NET public language runtime (CLR) also supports type constructor (also called static constructors, class constructors, or type initialization). Type constructors can be applied to interfaces, classes, and numerical types. It allows any initialization to be implemented before any members declared in the type. The type constructor does not require parameters and always returns a Void type. Type constructors only access the type of static field and its usual purpose is to initialize these fields. Before any instance of the type is created and any static field or method of the type is referenced, the type constructor has been run. Many languages (including C #) automatically generate type constructors when defined types. However, some languages require explicit (manual) implementation type constructors. In order to understand the type constructor, let's study the type defined in the C #: Class atype {static int x = 5;} When this code is established, the compiler automatically generates an ATYPE type constructor. This constructor is responsible for initializing the static field x as the value of 5. If you use ILDASM, it is easy to recognize the type constructor method because their names are .cctor (for class constructors). In C #, you can implement the type constructor by defining a static constructor method in the type. The use of keyword static means that this type constructor is not an instance constructor. The following is a very simple example: class atype {static int x; static atype () {x = 5;}} This type definition is the same as the previous. Note that type constructors must never try to create their own type instance, and constructors cannot reference the type of non-static member. Finally, if you compile the following code with the C # compiler, it produces a separate type constructor method: class atype {static int x = 5; static atype () {x = 10;}} This constructor first initializes x = 5, Then, X = 10 is initialized. In other words, the result type constructor generated by the compiler first contains the initialization code of the static field, followed by the code of the type constructor. Properties Many types of types defined can be re-obtained or modified. These properties are often implemented with members of the type field. For example, the following is a type definition containing two fields: Class Employee {public string name; public int32 aggra;} If you create this type of instance, you can easily get or set up the following code: Employee E = New Employee () E.NAME = "jeffrey richter"; // Setting the name attribute E.AGE = 36; // Setting the age property console.writeline (E.NAME); // Display "Jeffrey Richter" uses this manner very ordinary . But in my point of view, the above code will not be implemented as listed. One of the constant design and programming is the data abstraction. It means that the type field cannot be exposed to a public field because it is too easy to modify, it is too easy to write code that does not properly use this field, thereby destroying the status of the object.
For example, someone is easy to write the following code to destroy the EMPLOYEE object: E.AGE = -5; /// people age how it is -5? So, when designing types, I strongly recommend that all fields are private (private) or at least protected - Never public (public). Then, let the people who use the type of people can get or set attributes to provide methods for this. Methods for packaging access to fields are called an accessor (or accessor method) method. These methods can achieve integrity check at any time and ensure that the status of the object is not destroyed. For example, I rewrived the previously defined EMPLOYEE class, and the code is as shown in Figure. Although this is a simple example, you can understand the huge benefits of abstract data fields, you can also understand how to easily implement read-only properties, or just make only an accesser method to easily write only write properties . There are two shortcomings in the data abstraction method shown in Figure 1. First, because the additional function is to be implemented, it should be written more code. Second, the type of user must now call the method instead of only reference a single field name: E.SETAGE (36); // updates the agee.setage (-5); // throws an exception I think, all People will agree that these disadvantages are negligible with their advantages, but they still provide a attribute mechanism when running, which makes the first disadvantage to endure, and completely eliminate the second shortcomings. The classes in Figure II use the properties, their functions, and the class shown in the figure. As you can see, the property simplifies some code, but more important is to allow calls to write your own code as you: .age = 36; // Update age E.AGE = -5; // Throw an exception The return value of the THROWS AN Exception Get Attribute Accessor is the same as the SET attribute accessor parameter value. The return value of the set attribute accessor is Void, and the Get attribute accessor does not have an entry parameter. The attribute can be static, virtual, abstract, interior, private, protected or public. In addition, attributes can be defined in the interface, and this will be discussed later. I should also point out that attributes don't have to be associated with fields. For example, the type system.io.fileStream defines a length property that returns the number of bytes in the stream. When the length of the length attribute is called, this length is not provided by the field, but is called another function to request the underlying operating system to return the number of bytes that open the file stream. When you create properties, the compiler actually issues a dedicated GET_PRONAME and / or SET_PRONAME accessor method (here the Proname is the property name). Most compilers will understand these dedicated methods and allow developers to access these specificational methods for specialized syntax. However, compiled compilers comply with public language runtime does not need to fully support attributes, as long as the dedicated access method is supported. In addition, for a compiler that fully supports attributes, the syntax used in definition and use properties is slightly different, such as C with managed extensions, need to use the _property keyword. Index Properties Some types, such as System.Collections.SortedList Exposure Logical Element List. In order to easily access elements in this type, you can define an index property (called indexer -indexer).