"C # Advanced Series" 07 method

Source: Internet
Author: User

instance constructs and reference types

The previous chapters have actually written about the construction of reference types:

First of all, of course, in the heap, allocate memory for the instance object of the reference type, and then initialize the object's additional fields (that is, the type object pointer and the synchronization block index).

The memory allocated to the object at this time is directly set to 0, so if some of the fields in the object are not processed in the constructor used, the initial values for these fields should be 0 or null.

If a class, without a constructor, defines a default parameterless constructor, it simply calls the parameterless constructor of the base class.

In rare cases, there are cases where instances of a type can be created by an impractical instance constructor, such as when the MemberwiseClone method (deep copy) and deserialization of an object. (deserialization calls the Getuninitializedobject or Getsafeuninitializedobject method to allocate memory for an object, or later.) )

Remember from the previous chapter that inline initialization may cause performance problems:

Because each inline initialization actually takes the actions of these initialized fields into the code of the constructor ( Note that these operations are performed first, and then the operation of the actual constructor ). If there is only one constructor function, it will not have any effect. However, if there are multiple constructor functions, the code for this initialization field is inserted in the constructor functions.

So when there are multiple constructor parameters, and there is a lot of inline initialization in the code, there is a lot of redundant code in the actual generated code. This can be resolved in the following ways:

 Public classtroy{//inline initialization is not done        int_a; int_b;  PublicTroy () {//The initialization process is placed in a constructor parameter, which is generally the absence of a parameter constructor             This. _a =1;  This. _b =2; }         PublicTroy (inti): This()//in other constructors, call this ()        {        }         PublicTroy (intIintJ): This()        {        }    }

Instance construction and value types

A value type does not actually need to define a constructor, and the C # compiler does not embed the default parameterless constructor for value types inline at all.

Only value types that are nested in a reference type are initialized to 0 or null, and if it is a stack-based value type, it is required to be forced to initialize before reading, otherwise an error is expected.

The instance constructor of a value type is useful only if it is explicitly called, otherwise its fields are initialized to 0 or null. ( that is, the struct has no parameter constructor, as long as you do not show the call, then the parameterless constructor is not automatically called.) In fact, the C # compiler does not allow you to write an parameterless constructor in the struct, which, after all, is too easy to misunderstand .

Because C # does not allow value types to define parameterless constructors, value types are also not allowed to inline parameterize . (A static field can be initialized inline, because it is inside a type object, not an instance object)

Any constructor of a value type must be initialized with values for all fields of the value type.

There are also solutions to such troublesome settings:

     Public struct Troy {        publicint  A;          Public int b;          Public Troy (int  i) {            thisnew Troy ();   First Initialize all fields to 0 or null            / Initialize the field you want to play            a = i;        }    }

(I had to spit it out, I just wrote a small example of a value parameter initialization with VS myself, and was deleted by 360 as a virus.) )

About Type constructors

The first thing to understand is that the type constructor is actually constructed when the CLR allocates type object initialization in memory.

A type constructor is not allowed to have parameters, and of course it can only define a type constructor.

In fact, the type constructor must be private and not even allow the private modifier to be explicitly written, just to prevent developers from invoking it. Its invocation is always the responsibility of the CLR.

Simple examples:

class program    {        staticvoid Main (string[] args)        {            new  Troy ( );        }    }      Public class Troy {        static  Troy () {            Console.WriteLine (" I'll ask you 6 not 6?") ");        }    }

Construction process:

When the JIT compiler compiles a method, it looks at which types the code refers to. Any type that defines a type constructor, the JIT compiler checks whether the type constructor is executed against the current AppDomain. is not called, no is called. Because the CLR wants a type constructor to execute only once in each AppDomain, in order to not have multiple threads call the type constructor at the same time, a mutex thread synchronization lock is obtained when the first call to the type constructor is made. In this way, only one thread can be called, and the subsequent thread will have to use it to find that it has been called before the type constructor is called. (Because the type constructor is thread-safe, it's a good place to initialize any singleton objects inside.) )

Although you can define a type constructor in a value type, in fact, because the value type does not have type objects in the heap at all, the code inside the natural is not called.

About operator overloading

In fact, the CLR knows nothing about operator overloading because this is the syntax of the programming language.

When the C # language-written operator overload statement is compiled into IL code, it has actually become a function with the SPECIALNAME flag.

When the compiler sees the addition of this operator, it will see if there are several operands of the type that define the function named Op_addition (the real name of the post compiled), and the method parameter is compatible with the type of the operand.

So in an operator overload function, you must have a parameter of the same type as the one that is fixed for this overloaded method:

 Public class Troy {        publicstaticintoperator +(Troy A, Troy b) {             return Ten ;        }    }

About conversion operator methods

classProgram {Static voidMain (string[] args) {Troy obj=3;//Implicit conversion succeeded            stringA = obj;//because the conversion overload is displayed, this type of notation compiles            stringA = (String) obj;//Show Conversion Success        }    }     Public classTroy {//implicit conversion operator implicit overload         Public Static Implicit operatorTroy (Int32 num) {return NewTroy (); }        //explicit conversion operator explicit overload         Public Static Explicit operatorString (Troy Troy) {return "It's all my turn ."; }    }

As with the general-+-This operator overload, the actual generated IL code is replaced with a name, prefixed with OP_.

When the C # compiler detects that an object in the code expects to have a different type of object, go back and look for the op_implicit method in which the implicit conversion is defined in both types. Display similar.

You can refer to the definition of the decimal class to understand.

About extension methods

Let me tell you about myself, but I don't recommend using this stuff.

Because of the non-standard extension method, it will increase the difficulty of reading code and increase maintenance cost. (I'm really sure some people will write it all over.)

This thing was mentioned earlier in the study notes on refactoring, which is mainly used to solve the class library of other people's encapsulation, and can't add the function that you want.

19th. The Imperfect class library speaks of

In simple terms, it is prudent to use, the class you write do not use the extension method.

In addition, the extension method must be a static method defined in the top-level static class, and if it is in a nested class, the compilation will fail.

In fact, the extension method is only a static function in the general static object after the C # compiler compiles, but adds a [Extension] feature. In reality, however, this extensionattribute feature cannot be used in code and is generated automatically by the C # compiler.

About partial methods

A partial method is much like a partial class, but a method preceded by a partial modifier.

In this case, if other partial classes implement this method, then this method will be added, if not implemented, then this code will be ignored at compile time.

However, partial methods can only be used in partial classes and structs, and return types are always void, and no parameters can be decorated with out. This limitation is because the method may not exist at run time, so there is no return.

The partial method is always private, but the C # compiler prohibits the private adornment modifier explicitly from being written in front of the partial method. (and type constructors are similar at this point)

"C # Advanced Series" 07 method

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.