Directory:
4.1 All types are derived from System.Object
4.2 Type Conversions
4.3 Namespaces and Assemblies
4.4 Correlation of the runtime
4.1 All types are derived from System.Object
The runtime requires that each type eventually be derived from the System.Object type.
System.Object
Public instance method:
Equals: Returns True if two objects have the same value.
GetHashCode: Returns the object's hash code. If an object of a type is to be used as a build in a Hashtable collection, the type should override the modification method. Methods should provide a good distribution for different objects.
ToString: The full name of the default return type (this. GetType (). FullName). However, you often rewrite the method to return a string object that contains the state representation of the object.
GetType: Returns an instance of a type derived from type, indicating what type to call the GetType object. The returned type object can mate with the reflection class to get metadata information about the type of the object. GetType is a non-virtual method intended to prevent a class from overriding the method. Hides its type, which in turn destroys the security of the type.
Protected method:
MemberwiseClone: This non-virtual method creates a new instance of the type and sets the instance field of the new object exactly as the instance field of the This object. Returns a reference to the new instance.
Finalize: This virtual method is called after the garbage collector's interpretation of an object should be reclaimed as garbage, before the object's memory is actually reclaimed. The type of cleanup work that needs to be performed before the memory is reclaimed should override the method.
New Operator: The CLR requires that all objects be created with the new operator.
1. Calculate the number of bytes required for all instance fields defined in the type and all of its base types (up to System.Object). Each object on the heap requires some extra members (overhead members: Cost members), type Object pointers, and synchronous block indexes. The CLR uses these members to manage objects. The number of bytes in the extra member is counted to the object size.
2. Allocates the memory of the object by allocating the number of bytes required by the type from the managed heap. All bytes allocated are set to 0 (0).
3. Initialize the object's "type Object pointer" and "Synchronize Fast index".
4. Invokes the instance constructor of the type, passing the argument specified in the new call. Most compilers automatically generate code in the constructor to call the base class constructor. Each type of constructor is responsible for initializing the instance fields of the type definition. The constructor that eventually calls System.Object, which does not have an instance field, does nothing and simply returns.
New returns a reference (or pointer) to the new object after all of these operations have been performed.
4.2 Type Conversions
One of the most important features of the CLR is type safety.
The CLR allows an object to be converted to its actual type or to any of its base types.
Is and as Operation Fu Jian
Is checks whether the object is compatible with the specified type and returns a Boolcan value of true or false. The IS operator never throws an exception. If the object reference is Null,is the operator always returns false.
The as operator works the same way as coercion type conversions, except that it never throws an exception, and if the object cannot be transformed, the result is null.
4.3 Namespaces and Assemblies
Namespaces logically group related types, and developers can easily locate types through namespaces.
Using directives: reduces the amount of typing, allowing aliases to be created for a type or namespace.
4.4 Correlation of the runtime
A process may have multiple threads, which are assigned to a 1MB stack when the thread is created. The stack space is used to pass arguments to the method, and local variables defined inside the method are also on the stack. Stack is built from high memory to low memory address.
The simplest method contains the prologue code, which initializes the method before it starts the work, and also contains the "Epilogue" code, which is cleaned up after the method has finished working to return to the caller.
When the method is called, the address in the local variable that is the argument is pressed into the stack, using the shape of the called method to parametric the stack position. The return address is also pressed into the stack. The method being called returns to that location after the end.
When the JIT compiler converts the IL code in a method to a cost machine CPU instruction, it will notice all the types referenced inside the method. At this point the CLR confirms that all assemblies that have defined these types are loaded. Then, using the assembly's metadata, the CLR extracts information related to these types and creates some data structures (in the heap) to represent the type itself. (Data structures used by Type objects)
When you define a type, you define a static data field inside the type. The bytes that provide support for these static data fields are allocated in the type object itself. Each type object eventually contains a method table (the MethodDef method table), and each method in the method table has a corresponding record entry for the type definition.
After the CLR confirms that all type objects required by the method have been created, the code of the method is compiled, allowing the thread to execute the native code of the method.
Prologue code must be executed online stacks to allocate memory for local variables, as part of the method "Prologue" code, the CLR automatically initializes all local variables to null and 0. If the code attempts to access a local variable that has not yet been initialized, C # reports an error message: An unassigned local variable is used. The object (type instance) is then constructed to contain the type object pointer and the synchronization block index, as well as the instance fields. Any time a new object is created on the heap, the CLR automatically initializes the internal "type Object pointer" member to reference the type object corresponding to the object. Before invoking a type's constructor, the CLR initializes the synchronization block index and sets all instance fields of the object to null or 0. The new operator returns the memory address of the object.
when a static method is called: The CLR locates the type object that corresponds to the type that defines the static method. The JIT compiler then looks in the method table of the type object for the record entry corresponding to the called method, JIT-compiles the method, and invokes the compiled code. Internally, the static method constructs a new object on the heap, and returns the object address and saves it in the variable.
when calling a non-virtual instance method: The compiler will find the type object that corresponds to the type of the variable being called. If the type does not define the method being called, the JIT backtracking the class hierarchy (which goes back to System.Object) and finds the method in each type along the way. The JIT then looks for a record entry in the method table of the type's object that references the called method, JIT-compiles the method (if necessary), and then calls the JIT-compiled code.
when you invoke an instance method: The JIT compiler generates some extra code in the method, and the method executes the code each time it is called. The code first checks the variables that emit the call and follows the address to the variable that made the call. The code then examines the "type Object pointer" member inside the object, which points to the actual type of the object. The code then looks for the record entry in the method table of the type object that references the called method, compiles the method, and then invokes it.
Type objects are also objects in nature. These members must be initialized when the CLR creates type objects. When the CLR starts running in a process, it immediately creates a special type object for the System.Type type defined in MSCorLib.dll. All types of objects are instances of that type. The pointer member of the type object in the object is initialized to a reference to the System.Type type object.
The System.Type type object itself is also an object, and the internal "type Object pointer" points to its province because the System.Type type object is also an "instance" of a type object. The GetType method of System.Object returns the address stored in the type Object pointer member of the specified object. In other words, the GetType method returns a pointer to the object's type object. This makes it possible to determine the true type of any object in the system.
Fourth Chapter Type Foundation