C # Drill-down into generics

Source: Internet
Author: User

This article is based on the online & book summary.

1. Introduction

Generic programming is a style or paradigm of programming language. Generics allow programmers to write code in a strongly typed programming language using some types that are later specified, which are specified as parameters when instantiated (instantiate).

The. NET framework generic parameters can only represent classes and cannot represent individual objects. Because the actual type of the type parameter of the. NET framework generic is not eliminated at run time, the run speed is accelerated by a decrease in the number of type conversions. In addition, the GetType() method can be used to know the actual type of the generic and its type parameters when the program runs, and can also use reflection programming.

2. Why generics are required

Any API that uses object as a parameter type or return type may at some point involve coercion of type conversions. Designing only one class and taking object as the root hierarchy will make everything easier. However, the object type itself is an extremely ' dull ' existence. To do something really meaningful with an object, you almost have to force the type conversion.

Generics can have an enhanced performance, and the compiler can perform more checks at the first time, so you can do less when you perform a check. Second, JIT can intelligently handle value types, which can eliminate boxing and unboxing in many cases. In some cases, the results of generics and non-generics are quite different, both in terms of speed and memory consumption.

The benefits of generics are much like the advantages of static languages compared to dynamic languages: better compile-time checking, more information that can be directly represented in code, more IDE support, and better performance. The reason is simple, using a generic API that does not differentiate between different types (such as ArrayList), which is equivalent to accessing that API in a dynamic environment. By the way, conversely, the converse is usually not true: Dynamic languages have a number of advantages in many cases, but these cases rarely apply to the selection of generics and non-generic APIs. When you can reasonably use generics, you will usually not hesitate to choose Generics.

3. We use examples to learn

1) We use generics to create a method for creating a list:

         public list<t> makelist<t>(t A, T B)        {            returnnew List <T>() {A, b};        }

list<string> myList = MakeList ("str1", "str2");

As you can see from the example above, we can create a type that returns to ourselves as long as we pass in our own type.

2) Now let's go a little deeper.

Just as instance fields belong to an instance, static fields are subordinate to the type that declares them. If a static field x is declared in SomeClass, there is only one someclass.x field, regardless of how many instances of SomeClass are created, and regardless of the number of types derived from SomeClass.

Each enclosing type has its own set of static fields. We set the values of the fields for different enclosing types, and then we print the values to prove that they are independent.

Publicclass typewithfield<t>    {        publicstatic       string  field;          Public Static void Printfield ()        {            +""typeof(T). Name);        }    }

Below we print their values:

 typewithfield<int  >.field =  "f1   " ; Typewithfield  <string  >.field =  s2   "             ; Typewithfield  <datetime>.field =  "             T3   ; Typewithfield  <int  > <string  > <datetime>. Printfield (); 

You can see these values:

So, the basic rule is that each enclosing type has another static field. The same rules apply to static initializers and static constructors. However, a generic type may be nested within another generic type, and a type may have more than one generic parameter. It sounds complicated, but it works the same way you think.

4. How the JIT compiler handles generics

For all the different enclosing types, the JIT's duty is to convert the generic IL to cost code so that it can actually run. In some ways, we don't need to know what the exact conversion process is. Just pay attention to memory and CPU time. If the JIT generates local code for each enclosing type separately, as these types do not have any connection to each other, we will not feel much difference. But the JIT writers are very clever, and it is necessary to see what they have done.

First, let's look at a simple, one-type parameter case. To facilitate the discussion, we use list<t> as an example. The JIT creates different code for each enclosing type that takes a value type as a type argument. However, all enclosing types that use reference types (string, Stream, StringBuilder, and so on) as type arguments share the same native code. This can be done because all references have the same size (4 bytes on the 32-bit CLR and 8 bytes on the 64-bit CLR). However, in any particular CLR, all references have the same size). Regardless of what is actually referenced, the size of the referenced (constituted) array will not change. The space required for references on the stack is always the same. Regardless of the type of use, you can use the same register optimization measures, even the list<reason> is no exception.

As mentioned above, each type can also have its own static field, but the executable code itself can be reused. Of course, the JIT is still using the ' lazy people ' principle. No code will be generated for list<int> unless required. Once the code is generated, the code is cached for future use of list<int>.

In theory, at least for some value types, code can be shared. But the JIT must be very cautious, not only to consider the size, but also to consider the problem of garbage collection, JIT must be able to quickly identify a struct value of the reference is alive. However, if the value type has the same size, and the GC appears to have the same ' memory demand ', then it should be able to share the code.

C # Drill-down into generics

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.