. NET Development Basics: A simple example to understand generic sharing _ practical skills

Source: Internet
Author: User
Tags comparable readline

Understanding generics from a simple example
Say that there is a film and television companies to select the hero hero, the director said, male actors, height is kingly. So there's the following code:

Copy Code code as follows:

Male actor Entity class
public class Boy
{
Name
private string Mname;
Height
private int mheight;
public string Name {
get {return this.mname;}
}
public int Height {
get {return this.mheight;}
}

Public Boy (string name, int height) {
This.mname = name;
This.mheight = height;
}
}


Actor Selection Class
public class Compare
{
Director Guide Super Girl born, like one-on-one PK
Public Boy Whoisbetter (Boy boy1, Boy boy2)
{
if (boy1. Height > Boy2. Height)
{
return boy1;
}
Else
{
return boy2;
}
}
}


Test
static void Main (string[] args)
{
Boy boy1 = new Boy ("Panchangjiang", 165);
Boy boy2 = new Boy ("Andy Lau", 175);

Console.WriteLine (New Compare (). Whoisbetter (boy1, Boy2). Name);
Console.ReadLine ();
}


The code is simple, boy for the actor entity class, contains the name and height of two field attributes; the whoisbetter in the Compare class is the selection logic method, which is responsible for selecting the taller of the two male actors; test results: Andy Lau is a big victory.

Any industry is the same, and demand changes are everywhere. The next day, need to choose the heroine, the director said, actress, Slim is kingly. So the code changes, add the actress entity class, add the actress selection method:
Copy Code code as follows:

Add an actress entity
public class Girl
{
Name
private string Mname;
Weight
private int mweight;
public string Name
{
get {return this.mname;}
}
public int Weight
{
get {return this.mweight;}
}

    public Girl (string name, int weight) {
        this.mname = name;
        this.mweight = weight;
   }
}

 
//Actor Selection class add an actress method
public class Compare
{
   //actor height is king
     public Boy whoisbetter (Boy boy1, Boy boy2)
    {
         if (boy1. Height > Boy2. Height)
        {
             return boy1;
       }
        Else
        {
             return boy2;
       }
   }

Actress Slim is the king
Public Girl Whoisbetter (Girl girl1, Girl girl2)
{
if (GIRL1. Weight < Girl2. Weight)
{
return GIRL1;
}
Else
{
return GIRL2;
}
}
}


Test
static void Main (string[] args)
{
Boy boy1 = new Boy ("Panchangjiang", 165);
Boy boy2 = new Boy ("Andy Lau", 175);

Girl GIRL1 = new Girl ("Gong Li", 120);
Girl girl2 = new Girl ("Zhou Xun", 80);

Console.WriteLine (New Compare (). Whoisbetter (boy1, Boy2). Name);
Console.WriteLine (New Compare (). Whoisbetter (GIRL1, GIRL2). Name);
Console.ReadLine ();
}


As a result, Andy Lau, who was taller than the other, chose Zhou Xun, who had a lighter weight, and the director was satisfied. But from the design point of view, this code is obviously not perfect, the first day selected male lead, the next day to choose the heroine, and then choose a supporting actor, select a supporting actress, select the masses ... In the current way, only to the compare class to continue to add methods to meet the director's needs, the method will be more and more, the code will grow longer. So I decided to revise the Whoisbetter method so that it could later support the comparison between male, female, male, female, male and female, and even support all two objects:
Copy Code code as follows:

<summary>
Actor: Implement IComparable interface
</summary>
public class Boy:icomparable
{
Name
private string Mname;
Height
private int mheight;
public string Name {
get {return this.mname;}
}
public int Height {
get {return this.mheight;}
}

Public Boy (string name, int height) {
This.mname = name;
This.mheight = height;
}

public int CompareTo (object obj)
{
Compare height
Return This.mheight-((Boy) obj). Height;
}
}

<summary>
Actress: Implementing IComparable Interface
</summary>
public class Girl:icomparable
{
Name
private string Mname;
Weight www.jb51.net
private int mweight;
public string Name
{
get {return this.mname;}
}
public int Weight
{
get {return this.mweight;}
}

Public Girl (string name, int weight) {
This.mname = name;
This.mweight = weight;
}

public int CompareTo (object obj)
{
Compare weight
Return ((Girl) obj). Weight-this.mweight;
}
}


First let the entity class support a custom comparison, the male actor is taller, the actress compares the weight. Custom comparisons are accomplished by implementing the IComparable interface, in C # where any comparable type, such as int, double, char, implements the IComparable interface. The IComparable interface is not detailed here, please refer to the relevant information.
Copy Code code as follows:

public class Compare
{
Everything is object.
public Object Whoisbetter (object Obj1, Object obj2)
{
Object result = Obj2;
Judge the comparison type to be the same
if (obj1. GetType () = = Obj2. GetType ())
{
Switch (obj1. GetType (). ToString ())
{
Male actor Selection
Case "Generic.boy":
if ((Boy) obj1). CompareTo (OBJ2) > 0)
{
result = Obj1;
}
Break
Female actress Selection
Case "Generic.girl":
if ((Girl) obj1). CompareTo (OBJ2) > 0)
{
result = Obj1;
}
Break
Extended int Type comparison
Case "System.Int32":
if ((System.Int32) obj1). CompareTo (OBJ2) > 0)
{
result = Obj1;
}
Break
}
}
return result;
}
}

Modifying the Whoisbetter method, in addition to supporting comparisons of actors and actresses, adds a new type of int to show extensibility.
Copy Code code as follows:

Test
static void Main (string[] args)
{
Boy boy1 = new Boy ("Panchangjiang", 165);
Boy boy2 = new Boy ("Andy Lau", 175);

Girl GIRL1 = new Girl ("Gong Li", 120);
Girl girl2 = new Girl ("Zhou Xun", 80);

Console.WriteLine ((Boy) New Compare (). Whoisbetter (boy1, Boy2)). Name);
Console.WriteLine ((Girl) New Compare (). Whoisbetter (GIRL1, Girl2)). Name);
Console.WriteLine (New Compare (). Whoisbetter (boy1. Height, Boy2. Height));
Console.WriteLine (New Compare (). Whoisbetter (GIRL1. Weight, Girl2. Weight));

Console.ReadLine ();
}


Test results:
Andy lau
Zhou Xun
175
120
OK, so far, seems to be perfect, the actor than height, actress than weight, but also support int type size, Whoisbetter method has a reusability, if necessary, can be extended to compare any two objects. Before generics appear, it does seem to be perfect, but it's only relative, so let's look at the weaknesses of the current code:
Vulnerability 1: reusability of methods
Suppose we want to allow the Whoisbetter method to support more types, such as supporting the basic Double,char,bool type, supporting the future of the director may be proposed by comparison, the masses, then must continue to expand the method internal code, which brings great maintenance costs.
Vulnerability 2: type safety issues
Copy Code code as follows:

Test
static void Main (string[] args)
{
Boy boy1 = new Boy ("Panchangjiang", 165);
Boy boy2 = new Boy ("Andy Lau", 175);

Girl GIRL1 = new Girl ("Gong Li", 120);
Girl girl2 = new Girl ("Zhou Xun", 80);

Console.WriteLine ((Boy) New Compare (). Whoisbetter (boy1, GIRL1)). Name);
Console.ReadLine ();
}


As on the code, I compare Panchangjiang with Gong Li. Although omnipotent object brings us convenience, but also brings risks, this code can be compiled completely, but the runtime will be abnormal, girl object is not able to convert to boy type, the reality to Korea can be denatured, but the code is absolutely not. So this method is like a time bomb, accidentally passed the wrong parameters, will lead to serious consequences, and the compilation phase is not found at all.
Vulnerability 3: Performance issues caused by boxed unboxing
When an int parameter is passed to the Whoisbetter method, object conversion to int causes the unboxing operation:
if ((System.Int32) obj1). CompareTo (OBJ2) > 0)
To reverse-compile fetch MSIL:
IL_0093:unbox.any [Mscorlib]system.int32
C # is a strongly typed language, but as long as the reference type is converted to a value type, the box and unbox are not avoided. The information about boxing and unpacking is requested by the reader, and is not detailed here.

Understanding Generics
OK, to the generics debut, excerpt a description of generics in MSDN: generic classes and generic methods are reusable, type-safe, and efficient, which are not available for Non-generic and Non-generic methods. These three points coincide with the example above.
Look at the solution using generics:
Copy Code code as follows:

public class compare<t> where t:icomparable
{
Public T Whoisbetter (t T1, T T2)
{
if (T1.compareto (T2) > 0)
{
return t1;
}
Else
{
return T2;
}
}
}


Test
static void Main (string[] args)
{
Boy boy1 = new Boy ("Panchangjiang", 165);
Boy boy2 = new Boy ("Andy Lau", 175);

Girl GIRL1 = new Girl ("Gong Li", 120);
Girl girl2 = new Girl ("Zhou Xun", 80);

Console.WriteLine (New Compare<boy> (). Whoisbetter (boy1, Boy2)). Name);
Console.WriteLine (New Compare<girl> (). Whoisbetter (GIRL1, Girl2)). Name);
Console.WriteLine (New Compare<int> (). Whoisbetter (boy1. Height, Boy2. Height));
Console.WriteLine (New Compare<string> (). Whoisbetter (boy1. Name, Girl1. Name));
Console.ReadLine ();
}


This code, which has a great triumph over generics and reusability, can be said to support all types of comparisons, as long as the type implements the IComparable interface and, once and for all, no longer requires any extension within the method.
public class compare<t> where t:icomparable{
//...
}
The definition of a generic class is to keep up with <t&gt after the class name, which is a generic private syntax, and T represents the type to be passed in, and you can replace it with another letter.
Where t:icomparable is literally understood, this paragraph represents a type constraint on T. The program is to follow the human will to execute, according to the previous example, if inexplicably let the program compare two object, it has no way to know how to compare. So we have to tell the program that T must be a comparable type, T must implement the IComparable interface.
For generic parameter constraints, MSDN provides a table:

Constraint description
T: The struct type parameter must be a value type. You can specify any value type other than nullable.
T: The class type parameter must be a reference type, and this applies to any class, interface, delegate, or array type.
The t:new () type parameter must have a public constructor without parameters. When used with other constraints, the new () constraint must be last specified.
The t:< base class name > type parameter must be the specified base class or derived from the specified base class.
The t:< Interface name > type parameter must either be the specified interface or implement the specified interface. You can specify multiple interface constraints. The constraint interface can also be generic.
The type parameter provided by T:u for T must be a parameter supplied for u or a parameter derived from U.

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.