How exactly do the generic mechanisms commonly used by programmers play?


Author | Zhu Gang, Editor-in-Chief | Guo Rui

头 图 | CSDN Download from Oriental IC

Exhibition | CSDN (ID: CSDNnews)

Developers often use generics, and most developers will use generics very well. Generics need the support of the underlying runtime. The type parameters in the generic class become metadata, and they will be used to construct the appropriate class when needed at runtime. Therefore, generics support inheritance, polymorphism, and encapsulation. To briefly talk about the deep knowledge of generics, let's take a look at what is the internal mechanism of generics.

CIL means generic

After compiling, the generic class is not much different from the result of the ordinary class compilation. The result is CIL and metadata. The only difference is that CIL will use a special mark to indicate that the compilation result is a generic class. Compile the results, let's take a look at an example.

public class Demo<T> where T:IComparable


{


    //more code


    T[] item;


    //more code


}

The above code defines a Demo generic class, which contains a type parameter. The parameterized CIL code finally generated after mutation is as follows:

.class private auto ansi beforefieldinit Demo'1 <[mscorlib]System.IComparable)T> extends [mscorlib]System.Object


{


    //more CIL code


    .field private !0[ ] items


    //more CIL code


}

In the above parameterized CIL code, we see a '1' appearing after Demo, which is called the number of arguments, that is, the number of parameters, indicating the number of type arguments required when declaring a generic class. The above example has only one type Therefore, the number of type actual parameters he needs is one. If it is a generic class such as Demo <TKey, TValue, Tother>, the amount of type actual parameters in the generated parameterized CIL code is 3, which is expressed as' 3 . The constraints imposed on the class are shown in the parameterized CIL code, both [mscorlib] System.IComparable. At the same time, the CIL code modifies the declaration of the defined T type array, using! To include a type parameter. Except for the three points mentioned above, the other CIL code generated is no different from the code generated by ordinary classes.

Value type generic instantiation

When constructing a generic type with a value type as a type parameter, in order to create a concrete generic type, the runtime will put the specified type parameter in the appropriate location of the CIL.

When we call the generic class Demo defined in the previous section for the first time and pass int as a type argument to Demo, the runtime will generate a concrete version of Demo and use int to replace the type parameter. In this way, every time you use Demo <int>, the generated materialization class Demo <int> will be reused at runtime. It should be noted here that the generated materialized class is only for the case where the type argument is int. If a Demo with float as the type argument is defined at this time, another generic type will be generated at runtime. version.

Using value type generic instances can avoid code conversion and boxing operations to improve performance, but in the use process, you also need to judge whether value type generics should be used and how to use them according to specific codes, specific situations, and specific items.

Tip: The runtime will create a specific generic type for each new type-only parameter.

Reference type generic instantiation

Generic instances are a bit different from value types when using reference types as type arguments. When constructing a generic type, the runtime will use the object reference to replace the type parameter in the CIL code to create the materialized generic type. Whenever the constructed type is instantiated using the reference type parameter, the runtime will reuse the generated one Version, here you need to pay attention that if the reference type provided is different from the reference type when constructing the generic type, it will still use the version that has been generated. Let's look at an example:

Demo<User> userDemo;


Demo<Student> studentDemo;

First of all, when the code runs to the first line, a specific version of Demo will be generated at runtime. CIL will not store User as the specified data type, but store the object reference. Then when the code runs to the second line, although the references of Student and User are different, CIL will not create a new materialized version of Student, but will instantiate the Demo instance of the object reference given earlier. Of course, in order to ensure type safety, CIL will allocate a memory area of ​​the Order type to replace each object reference of the type parameter to this memory area. The benefit of using reference type generics is that the compiler compresses the materialized classes it creates to one, so it greatly reduces the amount of code and improves the performance of the code.

It should be noted here that the reference type parameter uses the same internal generic type definition when it changes, but if the following situation occurs, then the same internal generic type definition will not apply.

Demo<int,User> userDemo;


Demo<long,User> userLongDemo;


Demo<Guid,User> userGuidDemo;

In the above code, the type parameter contains the value type. At this time, the same internal generic type definition will not be used, but a different internal type definition will be created for each Demo.

summary

Although this article is short, it fully explains the internal principles of the generic mechanism and related precautions. Generics in .NET are arguably the best. The use of generics in Java is completely implemented in the compiler rather than in the JVM. Although this prevents the use of generics and the distribution of new JVMs, it is because It does not distinguish between value types and reference types, so the implementation efficiency and affect the use of the reflection part.

Author: Zhu steel, .NET senior development engineer, 7 years of front-line development experience, participated in the development of e-government systems and AI customer service systems, and Internet recruitment site architecture, currently working in Beijing Chong Heng Rong-hui Technology Development Co., Ltd.

Disclaimer: This article is an original submission by the author, please do not reprint without permission.

【END】

More exciting recommendations

A century of IBM finally All In artificial intelligence and hybrid cloud!

☞ Microsoft, Apple, Google, Samsung ... These technology giants in the blockchain have already done so many things!

☞Winning GitHub 2000+ Star, how does Alibaba Cloud's open source Alink machine learning platform outperform the double 11 data "game"? | AI Technology Ecology

☞Microsoft acquired a company for one person? Crack Sony programs, write hacker novels, and watch his tough program life!

Machine learning project template: 6 basic steps of ML project

☞IBM, Microsoft, Apple, Google, Samsung ... These technology giants in the blockchain have already done so many things!

Summary by senior programmers: I will tell you all 6 ways to analyze the Linux process

Today's Welfare: If you leave a comment in the comment area, you can get a ticket for the live broadcast of the "2020 AI Developer Ten Thousand Conference" worth 299 yuan . Come and move your finger and write what you want to say.

Click to read the original text, wonderful to continue!

Every "watching" you order, I take it seriously

Published 1940 original articles · 40 thousand likes + · 18.13 million views

Guess you like

Origin blog.csdn.net/csdnnews/article/details/105424407