Chapter 9
First, instance constructors
1. The three songs when using the New operator to create an object:
l Assign memory for objects
l Addition members of the initialization object (method pointer and syncblockindex)
l call instance constructors to initialize instance status
When allocating memory, the system is set to zero 0 value, which is a 0 or NULL value when the field initialization is not assigned.
Do not call the case of the instance constructor:
l Call the object.memberwiseclone () method creates an instance (allocated memory; initialize the additional member; copy the source object byte to the newly created object)
l When the reverse sequence is
2. To avoid excessive constructor code for the instance field, avoid the initial value of the field in the declaration field, but in the unfolded constructor, the initial value, call in other overloaded constructors No group constructor.
3, value type instance constructor
The LC # compiler does not automatically call its constructor, and the constructor must be explicitly invoked to work.
The LC # compiler does not allow the value type to define no unfolded instance constructors (the following can be described below)
l Cannot assign initial values to the fields in the structure, can be performed by defining a reference fabric
l You must assign all fields in the constructor of the structure.
Second, type constructors
1. Some limitations of type constructors:
l Can not bring any parameters
l Type constructors are always private, and other access modifiers cannot be used.
2, the timing of the type constructor is called:
l The first instance is created, or the first field or member of the type is first accessed.
l Non-inherited static fields were previously accessed
Type constructors are only called once in the life cycle of the type;
3, some restrictions:
l If the exception is thrown in the type constructor, the type becomes inaccessible, and any field or method accessed will throw the System.TypeinitializationException.
l Type constructor can only access the type of static field
l Type constructors should call the type constructor of the base type, because the static field is not inherited, but the static binding is compiled.
Third, operator overload
1, operator overload
Some restrictions on operator overload in C #:
l must be declared as public static
l Must have a parameter to be the type of operator.
l The number of quotes that cannot change the original definition of operators
l If the True operator must also define the FALSE operator, both must return BOOL value.
L , - operators must return an example of its belongings
l One dollar operator that can be overloaded: , - ,! , ~, , -, true, false
l The binary operator that can be overloaded: , -, *, /,%,! , ^ (No or), <,>, <<, >>, ==,! =, <=,> =
l Not allowed to be overloaded: &&, ||, = ,? :, =, - =, / =,% =, | =, ^ =, << =, >> =, in fact, some "duplex operators" automatically generate after the binary operator is overloaded, and Can't explicitly define
l Must be used to overload operators: (==,! =), (<,>), (<=,> =)
L , - can not distinguish when the operator is overloaded
2, operator overload and language interoperability
The compiler will generate a special name for the overloaded operator, such as the (plus) operator generates the op_addition () method, and adds the SpecialName tag to the definition entry of the method. When a language cannot be overloaded, it is possible to directly define a method with the special name to be called in other languages; or directly call the method with this special name to accommodate the limitations of the operator. If the operator cannot be overloaded in VB, the op_addition () method can be explicitly defined to call in C #; the operator defined in the C # cannot be identified by VB, which can explicitly call the op_addition () method to obtain the same function. Fourth, conversion operators
Some restrictions on the conversion operator:
l must be public static
l Must specify keyword Implicit or ExPlicit, principle to convert from this type to other types of Implicit, convert other types to this type with explicit, can not be used in IMPLICIT
V. Method parameters
1, reference parameters
l Default to the value
l The parameters of the OUT, do not initialize before the call method is called, but must be assigned before returning, and the parameters that are not initialized cannot be used.
l The parameters of the REF, must initialize before the call method, otherwise trigger compilation error
l You can use REF or OUT to perform the overload of the method, but cannot be overloaded by distinguishing REF and OUT.
l Press the variable (arguments) of the reference mode (inform) must be identical to the parameter (ginseng) type of the method declared, otherwise the compilation error is triggered.
2, variable number parameters
Specify variable parameter sequences using the params keyword and an object array. Some restrictions:
l Only the last parameter of the method can use variable number parameters.
Sixth, virtual method
1. Calling mechanism for virtual method
CLR uses two IL instructions to call methods:
UCALL calls a method according to the type (ie, the quote, a declaration type)
UcallVirt calls a method based on objects (ie, reference dynamic types, actual types)
The case where the virtual method is used to use Call:
LBASE. virtual method ()
l Sealing type references the false method, because there is no need to verify the actual type of sealing type
L value type to avoid packing
Use the CallVirt to call the non-virtual method:
l When using the variable to null, use CallVirt to throw the system.nullreferenceException exception, and Call will not thrown
Regardless of the Call or Callvirt call method, there will be an implicit THIS pointer as the first parameter of the method, which points to the object being operated.
2, version of the virtual method:
Use the following example:
Using system;
Class Baseclass
{
Public void nonvirtualfunc ()
{
Console.writeline ("Non Virtual Func In Base Class);
}
Public Virtual Void VirtualFunc ()
{
Console.writeline ("Virtual Func In Base Class);
}
}
Class DevicedClass: Baseclass
{
// If you don't use the new key, the compiler will have WARNING:
// "DeviceDclass.nonvirtualFunc ()" request keyword
// New because it hides the inheritance member "Baseclass.nonvirtualFunc ()"
Public new void nonvirtualfunc () {
Console.writeline ("Non Virtual Func In Deviced Class);
}
// If you do not add keyword override or new, the compiler will have Warning:
// "DeviceDclass.VirtualFunc ()" Baseclass.VirtualFunc () "Baseclass.VirtualFunc ()" BaseClass.VirtualFunc () "
/ / To rewrite the implementation of the current member, add the keyword override. Otherwise, add a keyword new.
Public override void virtualfunc ()
{
Console.writeline ("Virtual Func in Deviced Class);
}
}
Class testclass
{
Public static void
Main
()
{
// Derived instance call non-virtual and virtual functions
DeviceDClass DC = New DevicedClass ();
Dc.nonvirtualfunc ();
Dc.Virtualfunc ();
// base class instance call non-virtual and virtual function
Baseclass bc = new baseclass ();
bc.nonvirtualfunc ();
bc.virtualfunc ();
// Point to the base class reference call from the derived class instance call non-virtual and virtual functions
BaseClass BC1 = DC;
BC1.NONVIRTUALFUNC ();
BC1.VIRTUALFUNC ();
}
}
/ *
Use the keyword Override to run the result:
Non Virtual Func in Deviced Class
Virtual Func in Deviced Class
Non Virtual Func in Base Class
Virtual Func in base Class
Non Virtual Func in Base Class
Virtual Func in Deviced Class
* /
/ *
Use the keyword new run results on the virtual function
Non Virtual Func in Deviced Class
Virtual Func in Deviced Class
Non Virtual Func in Base Class
Virtual Func in base Class
Non Virtual Func in Base Class
Virtual Func in base Class
* /
It can be seen from the above: New and Override Coordinate the version control in the derived class, which has seen Oeverride only for the Virtual method in Chapter 7, and New is available for non-virtual or virtual methods to implement the same name in the hidden base class. method. Use Override on the virtual function, to rewrite the basic class, there is no hidden, which also implements a polymorphism. We can imagine that NEW uses the CALL instruction to call the static type method, and Override uses the CallVirt command to call the dynamic type method.
I hope this example is helpful to your understanding.