http://blog.163.com/chenhui_761217/blog/static/340737792010912103043831/
How to understand the default () method:
The default keyword is used because it is necessary to assign an initial value to an object instance without knowing whether the type parameter is a value type or a reference type. Consider the following code:
Class testdefault<t>
{
Public T foo ()
{
T t = null; //???
return t;
}
}
if we bind a generic argument with an int, then T is an int, then the annotation line becomes int t = null; Obviously it's meaningless. To address this problem, the default keyword is introduced:
Class testdefault<t>
{
Public T foo ()
{
return default (T);
}
}
-----------------------The following is the original--------------------------
Generics Overview
First, let's look at an example of a data structure that is common before generics appear
Universal Data Structure class Code
Public class stack
{
object[] m_Items;
public stack ()
{ }
public void push (Object item)
{
public object pop ()
{ }
Invoke Instance Code
public partial class _default:system.web.ui.page
{
protected void Page_Load (object sender, EventArgs e)
{
Stack stack = new stack ();
Stack. Push (1);//Boxing
Stack. Push (2);//Boxing
int number = (int) stack. Pop ();//Split Box
}
}
And then we'll look at the problems that are based on the above object solution
1. Due to the frequent occurrence of value-type boxing and unboxing in the actual call, this will lead to a lot of waste debris, increasing the burden of garbage collection; The problem with reference types is not to be underestimated.
2. Compile-time task types can be converted to object and cannot guarantee Run-time type security. Look at the code below, compile pass, run times wrong: code
public partial class _default:system.web.ui.page
{
protected void Page_Load (object sender, EventArgs e)
{
Stack stack = new stack ();
Stack. Push ("test");
This sentence is clearly wrong, but the compilation can be done by
int number = (int) stack. Pop ();
}
}
So it has been suggested that, since the generic data structure class is not in object type, then I can use a specific type to replace the object type in the above struct class to handle a particular type of stack, which solves both of these problems, but the following problems occur:
1. Affect work efficiency.
Because you first have to predict that there are a number of specific types to use the above generic structure class, and then you have to write different classes based on these different types
2. Code redundancy, low reuse rate, which is obvious
3. A change in a data structure is to modify all types of data structures accordingly.
Because you want to modify all the specific types of data structures that are implemented based on this data structure
4. To provide support for unpredictable data types, or to provide an object-type interface, the old problem arises
In response to the above problems, it seems that there is no way to solve the problem, but after 2.0 Microsoft launched a generic data structure, can be a good solution to the above problems.
What is generics?
By generics you can define type-safe classes without compromising type safety, performance, or productivity, we can Code the following structure class
public class Stack
{
Object[] M_items;
Public Stack ()
{ }
public void Push (object item)
{ }
public Object Pop ()
{ }
}
Modify to Code
public class Stack<t>
{
T[] M_items;
Public Stack ()
{ }
public void Push (T item)
{ }
Public T Pop ()
{ }
}
Run-time instantiation
1. You can use any type declaration and instantiation
2. Declarations and instantiations must use a specific type instead of a generic type
3. The advantage of the generic programming model is that internal algorithms and operations remain unchanged, while the actual type can specify Code when used
public partial class _default:system.web.ui.page
{
protected void Page_Load (object sender, EventArgs e)
{
stack<int> stack = new stack<int> ();
Stack. Push (1);
Stack. Push (2);
int number = stack. Pop ();
}
}
how generics are implemented.
1. In. Net2.0, generics have native support in the IL and the CLR itself
2. When compiling types, just like compiling other types, generics retain only one placeholder
3. Instead of instantiating generic code with a specific type, the generics are substituted for the specific actual type at compile time
Benefits of Generics
1. One-time development, testing, and deployment of code to reuse it through any type (including future types)
2. Compiler support and type safety
3. Performance is significantly improved by not forcing boxing and unboxing of value types, or by forcing type conversions downward on reference types. For value types, the general increase is 200%, and for reference types, it can also be increased by 100% (of course, the entire application may or may not be running more efficiently.)
using generics in the structure body
Defining the general structure body Code
public struct point<t>
{
public T x;
Public T y;
}
Run instance Code
Point<int> Point;
Point.x = 1;
Point.y = 2; Code
Point<double> Point;
Point.x = 1.2;
POINT.Y = 2.3;
Default Method
In the generic generic structure class above, if you do not want an exception to be thrown when the stack is empty, but instead want to return the default value of the storage type in the stack, you will use the defaults method. This method is primarily used to get the default values for generic type parameters in the generic programming model
-default (valuetype) = 0;
-default (referencetype) =null;
For example, if the above stack<t>, use Default (T) to get the defaults.
Multiple generics
A single type can specify multiple generics
For example, Custom<k,t>,custom is the type, K is the first generic of this type, T is the second generic, and if more words are used, separate.
Generic alias
Alias a specific type using the Using keyword in the file header
Alias scope is the entire file, the implementation of Code
Using System;
Using System.Collections.Generic;
Using System.Web;
Using System.Web.UI;
Using System.Web.UI.WebControls;
Using Stack = stack<int>;
public partial class _default:system.web.ui.page
{
protected void Page_Load (object sender, EventArgs e)
{
Stack stack = new stack ();
Stack. Push (1);
Stack. Push (2);
int number = stack. Pop ();
}
}
generic constraint-derivation constraint
Why do I use generic constraints, first look at the following methods
public class LinkedList
{
T find (K key)
{
node<k,t> current = M_head;
while (current. Nextnode!=null)
{
Because the compiler does not know whether the K-type key supports the "= =" operator, for example, by default, the struct does not provide this implementation
if (current. Key==key)//will not Compile
{
Break
}
Else
{
Current=current. NextNode;
}
}
Return to current. Item;
}
}
According to the above note, this method is not compiled, then what method to solve it, we think of the following IComparable CompareTo method, as follows:
public interface IComparable
{
int CompareTo (object obj);
}
The solution is as follows:
public class linkedlist<k,t> where K:icomparable
{
T find (K key)
{
node<k,t> current = M_head;
while (current. Nextnode!=null)
{
Because the compiler does not know whether the K-type key supports the "= =" operator, for example, by default, the struct does not provide this implementation
if (current.Key.CompareTo (Key) ==0)//will not Compile
{
Break
}
Else
{
Current=current. NextNode;
}
}
Return to current. Item;
}
}
Note: The 1.where keyword, if the K and T are constrained in the above class, then two where is separated by a space
2.k:icomparable indicates that K only accepts types that implement the IComparable interface
3. Nevertheless, it is not possible to avoid packing problems with the passing of K of the value type, because the parameters of the CompareTo method under IComparable are still type object. So the final correct code is as follows:
public class linkedlist<k,t> where k:icomparable<t>
{
T find (K key)
{
node<k,t> current = M_head;
while (current. Nextnode!=null)
{
Because the compiler does not know whether the K-type key supports the "= =" operator, for example, by default, the struct does not provide this implementation
if (current.Key.CompareTo (Key) ==0)//will not Compile
{
Break