C# 参考:泛型(3) 应用泛型

因为 IL 和 CLR 为泛型提供本机支持,所以大多数符合 CLR 的语言都可以利用一般类型。例如,下面这段 Visual Basic .NET 代码使用代码块 2 的一般堆栈:
Dim stack As Stack(Of Integer)
stack 
= new Stack(Of Integer)
stack.Push(
3)
Dim number As Integer
number 
= stack.Pop()
您可以在类和结构中使用泛型。以下是一个有用的一般点结构:
public struct Point
{
   
   
public T X;
   
   
public T Y;
}

 可以使用该一般点来表示整数坐标,例如:

Point point;
point.X 
= 1;
point.Y 
= 2;

或者,可以使用它来表示要求浮点精度的图表坐标:

Point point;
point.X 
= 1.2;
point.Y 
= 3.4;

    除了到目前为止介绍的基本泛型语法以外,C# 2.0 还具有一些泛型特定的语法。
    例如,请考虑代码块 2 Pop() 方法。假设您不希望在堆栈为空时引发异常,而是希望返回堆栈中存储的类型的默认值。如果您使用基于 Object 的堆栈,则可以简单地返回 null,但是您还可以通过值类型来使用一般堆栈。为了解决该问题,您可以使用 default() 运算符,它返回类型的默认值。

下面说明如何在 Pop() 方法的实现中使用默认值:

public T Pop()
{
   m_StackPointer
--;
   
if(m_StackPointer >= 0)
   
{
      
return m_Items[m_StackPointer];
   }

   
else
   
{
      m_StackPointer 
= 0;
      
return default(T);
   }

}

引用类型的默认值为 null,而值类型(例如,整型、枚举和结构)的默认值为全零(用零填充相应的结构)。因此,如果堆栈是用字符串构建的,则 Pop() 方法在堆栈为空时返回 null;如果堆栈是用整数构建的,则 Pop() 方法在堆栈为空时返回零。

多个一般类型:
单个类型可以定义多个一般类型参数。例如,请考虑代码块 3 中显示的一般链表。 

代码块 3. 一般链表
class Node
{
   
public K Key;
   
public T Item;
   
public Node NextNode;
   
public Node()
   
{
      Key      
= default(K);
      Item     
= defualt(T);
      NextNode 
= null;
   }

   
public Node(K key,T item,Node nextNode)
   
{
      Key      
= key;
      Item     
= item;
      NextNode 
= nextNode;
   }

}


public class LinkedList
{
   Node m_Head;
   
public LinkedList()
   
{
      m_Head 
= new Node();
   }

   
public void AddHead(K key,T item)
   
{
      Node newNode 
= new Node(key,item,m_Head.NextNode);
      m_Head.NextNode 
= newNode;
   }

}

该链表存储节点:
class Node
{}

每个节点都包含一个键(属于一般类型参数 K)和一个值(属于一般类型参数 T)。每个节点还具有对该列表中下一个节点的引用。链表本身根据一般类型参数 K 和 T 进行定义:
public class LinkedList
{}

这使该列表可以公开像 AddHead() 一样的一般方法:

public void AddHead(K key,T item);

每当您声明使用泛型的类型的变量时,都必须指定要使用的类型。但是,指定的类型实参本身可以为一般类型参数。例如,该链表具有一个名为 m_Head 的 Node 类型的成员变量,用于引用该列表中的第一个项。m_Head 是使用该列表自己的一般类型参数 K 和 T 声明的。

您需要在实例化节点时提供类型实参;同样,您可以使用该链表自己的一般类型参数:

public void AddHead(K key,T item)
{
Node newNode = new Node<K,T>(key,item,m_Head.NextNode);
m_Head.NextNode = newNode;
}

请注意,该列表使用与节点相同的名称来表示一般类型参数完全是为了提高可读性;它也可以使用其他名称,例如:

public class LinkedList
{...}

或:

public class LinkedList
{...}

在这种情况下,将 m_Head 声明为:

Node m_Head;

当客户端使用该链表时,该客户端必须提供类型实参。该客户端可以选择整数作为键,并且选择字符串作为数据项:

LinkedList list = new LinkedList();
list.AddHead(123,"AAA");

但是,该客户端可以选择其他任何组合(例如,时间戳)来表示键:

LinkedList list = new LinkedList();
list.AddHead(DateTime.Now,"AAA");

有时,为特定类型的特殊组合起别名是有用的。可以通过 using 语句完成该操作,如代码块 4 中所示。请注意,别名的作用范围是文件的作用范围,因此您必须按照与使用 using 命名空间相同的方式,在项目文件中反复起别名。

代码块 4. 一般类型别名

using List = LinkedList;

class ListClient
{
   
static void Main(string[] args)
   
{
      List list 
= new List();
      list.AddHead(
123,"AAA");
   }

}


原文地址:https://www.cnblogs.com/Dlonghow/p/1240507.html