[Programming IL] Generic, Generic Types

Source: Internet
Author: User
Tags mscorlib
Document directory
  • Introduction:
  • 1. Define a generic class
  •  
  • 2. Define Constraints
  • Reference
Introduction:

Since the birth of generics, the love of many object-oriented programmers is generally higher than that of other data structures. :). However, the support of various object-oriented programmers is not the same. In CPP, static compilation is used, that is, the compiler determines the generic type, while. Net determines at runtime. What are their differences?

I talked with my colleagues about generics and found that everyone was familiar with this and thought it was necessary to make an application summary. Because there are many fan content, please refer to the following:

Let's start with C # defining a piece of basic fan code.

   1: public class GenericType<T> : IComparable<T>, IComparable<GenericType<T>>
   2:                     where T: IComparable
   3: {
   4:     public T Value;
   5:     
   6:     public int CompareTo(T t)
   7:     {
   8:         return this.Value.CompareTo(t);
   9:     }
  10:     
  11:     public int CompareTo(GenericType<T> t)
  12:     {
  13:         return this.Value.CompareTo(t.Value);
  14:     }
  15: }

Decompiled IL code

   1: .class public auto ansi beforefieldinit GenericType`1<([mscorlib]System.IComparable) T>
   2:        extends [mscorlib]System.Object
   3:        implements class [mscorlib]System.IComparable`1<!T>,
   4:                   class [mscorlib]System.IComparable`1<class GenericType`1<!T>>
   5: {
   6:   .field public !T Value
   7:   .method public hidebysig newslot virtual final 
   8:           instance int32  CompareTo(!T t) cil managed
   9:   {
  10:     // Code size       24 (0x18)
  11:     .maxstack  8
  12:     IL_0000:  ldarg.0
  13:     IL_0001:  ldflda     !0 class GenericType`1<!T>::Value
  14:     IL_0006:  ldarg.1
  15:     IL_0007:  box        !T
  16:     IL_000c:  constrained. !T
  17:     IL_0012:  callvirt   instance int32 [mscorlib]System.IComparable::CompareTo(object)
  18:     IL_0017:  ret
  19:   } // end of method GenericType`1::CompareTo
  20:  
  21:   .method public hidebysig newslot virtual final 
  22:           instance int32  CompareTo(class GenericType`1<!T> t) cil managed
  23:   {
  24:     // Code size       29 (0x1d)
  25:     .maxstack  8
  26:     IL_0000:  ldarg.0
  27:     IL_0001:  ldflda     !0 class GenericType`1<!T>::Value
  28:     IL_0006:  ldarg.1
  29:     IL_0007:  ldfld      !0 class GenericType`1<!T>::Value
  30:     IL_000c:  box        !T
  31:     IL_0011:  constrained. !T
  32:     IL_0017:  callvirt   instance int32 [mscorlib]System.IComparable::CompareTo(object)
  33:     IL_001c:  ret
  34:   } // end of method GenericType`1::CompareTo
  35:  
  36:   .method public hidebysig specialname rtspecialname 
  37:           instance void  .ctor() cil managed
  38:   {
  39:     // Code size       7 (0x7)
  40:     .maxstack  8
  41:     IL_0000:  ldarg.0
  42:     IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  43:     IL_0006:  ret
  44:   } // end of method GenericType`1::.ctor
  45:  
  46: } // end of class GenericType`1

We split it into several simple parts for discussion.

1. Define a generic class

This part can be split

  • Declare a class
       1: .class public GenericType <([mscorlib]System.IComparable) T>
       2:     extends [mscorlib]System.Object
       3:     implements class [mscorlib]System.IComparable<!T>
       4:                class [mscorlib]System.IComparable<class GenericType<T>> 
       5: {
       6: }

Unlike declaring a non-generic class

       1: <([mscorlib]System.IComparable) T>
  • Declare Variables
       1: .class public value Pair<T>
       2: {
       3:     .field public !T x
       4:     .field public !T y    // fields x and y have the same type T
       5: }
  • Declaration Method
       1: .class public List`1<T>
       2: {
       3:     .method public void Append(!T val) { ... }
       4:     .method public !T GetLast() { ... }
       5:     //...
       6: }
  • Hide and overwrite

In this section, the implementation of the generic type is consistent with that of the Non-generic type. We can view an instance

We define two methods for the previously defined GenericType.

   1: public void BaseRun()
   2: {
   3:     Console.WriteLine("This is the base Run");
   4: }
   5:  
   6: public virtual void ParentMethod()
   7: {
   8:     Console.WriteLine("The is the parentVirtual Method");
   9: }

Define a base class DerivedClass for him.

   1: public class DerivedClass<T> : GenericType<T> 
   2:             where T : IComparable
   3: {
   4:     public new void BaseRun()
   5:     {
   6:         Console.WriteLine("This is the derived class running");
   7:     }
   8:     
   9:     public override void ParentMethod()
  10:     {
  11:         Console.WriteLine("This is the derived class");
  12:     }
  13: }

Compare the generated IL code

   1: .method public hidebysig instance void  BaseRun() cil managed
   2: {
   3:   // Code size       11 (0xb)
   4:   .maxstack  8
   5:   IL_0000:  ldstr      "This is the derived class running"
   6:   IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
   7:   IL_000a:  ret
   8: } // end of method DerivedClass`1::BaseRun
   9:  
  10: .method public hidebysig virtual instance void 
  11:         ParentMethod() cil managed
  12: {
  13:   // Code size       11 (0xb)
  14:   .maxstack  8
  15:   IL_0000:  ldstr      "This is the derived class"
  16:   IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  17:   IL_000a:  ret
  18: } // end of method DerivedClass`1::ParentMethod
2. Define Constraints

Let's use IL to explain the constraints mentioned above.

  • Value Type Constraints

       1: .class public ClassType`1<valuetype .ctor ([mscorlib]System.ValueType) T>
       2:        extends [mscorlib]System.Object
       3: {}
  • Reference Type Constraints
       1: .class public ClassType`1<class T> extends [mscorlib]System.Object
  • Interface Type Constraints
  • Refer to the code above this article
  • Base Constraint
       1: .class public BaseClass`1<(class GenericType`1<!T>, [mscorlib]System.IComparable) T>
       2:        extends [mscorlib]System.Object
  • No parameter constructor Constraints
       1: .class public auto ansi beforefieldinit CtorType`1<.ctor T>
       2:        extends [mscorlib]System.Object
  • Multiple generic type relationship Constraints
       1: .class public ParentChild`2<T, (!T)U> // U must bedescendant of T
       2: {
       3:     //TODO:: Implement this ...
       4: }
  • (! T) U indicates that U must be a subclass that can be converted to T by type conversion, that is, U is T.
  • Come to a complex point
   1: .class public auto ansi beforefieldinit ComplexType`1<class .ctor ([mscorlib]System.IComparable) T>
   2:        extends [mscorlib]System.Object

We can see that the differences between several types only exist in <type definition>

Here, I still don't understand. Although the things at the IL level are quite concise, how are the advantages of generics realized? It's no surprise to see the definition of metadata.

Metadata definition:

Generic Param (Generic parameter), that is, <type definition>:

GenericParam Metadata Table:

Name Function

Number (2-byte unsigned integer ).

Location of generic parameters in a generic type

Flags (2-byte bit field ).

Generic Constraints

Owner (coded token of type TypeOrMethodDef ).

Generic parameters

Name (offset in the # Strings stream ).

Generic parameter name

Generic Method (Generic Method ):

   1: <gen_method_def> ::=
   2: .method <flags> <call_conv> <ret_type> <name>< <gen_params> > (<arg_list>) <impl>
   3: { <method_body> }
   4: For example:
   5: .method public static !!T GetMedian<T>(!!T[] tarray)
   6: {
   7:     ldarg.0
   8:     dup
   9:     ldlen
  10:     ldc.i4.1
  11:     shr
  12:     ldelem !!T
  13:     ret
  14: }

About CLR, it seems difficult to find relevant information during runtime creation, which needs to be further explored. :) this article has been written intermittently for a long time. First, draw a full stop.

Reference
  • Expert IL runner er 2.0
  • Professional. Net 2.0 Generic
  • ECMA Partion II

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.