C#中的泛型

C#泛型:(C# Generics)
   (广泛的类型)
   通过泛型可以定义类型安全类,而不会损害类型安全,性能或工作效率
  
   例:
   public class Stack<T>
{
    T[] m_Items;
    public void Push(T item)
   {
                ...
   }
   public T Pop()
  {
               ...
  }
}
  
   使用:
   C#语法:
   Stack<int> stack=new Stack<int>();
   stack.Push(1);
   stack.Push(2);
   int number=stack.Pop();
  
   VB语法:
   Dim stack As Stack(Of Integer)
   stack=new Stack(Of Integer)
   stack.Push(3)
   Dim number As Integer
   number=stack.Pop();
  
   可以使用任何类型来声明和实例化
   声明和实例化时都必须用一个特定的类型来代替
   一般类型T
  
   泛型是如何实现的:
   在.Net2.0中,泛型在IL(中间语言)和CLR本身中
   具有本机支持
  
   编译泛型类时,就像编译其他类一样,泛型仅保留一个占位符
  
   而用特定类型实例化泛型代码,编译时会将
   泛型替换为实例化的特定类型.
  
   泛型的好处:
  
   一次性地开发,测试和部署代码
   通过任何类型(包括将来的类型)来重用它:
  
   编译器支持和类型安全
  
   不会强行对值类型进行装箱和取消装箱
   或者对引用类型进行向下强制类型转换
   所以性能得到显著提高
  
   在结构中使用泛型:
  
   public struct Point<T>
   {
public T x;
public T y;
   }
  
   Point<int> point;
   point.x=1;
   poing.y=2;
  
   Point<double> point;
   point.x=1.2;
   poing.y=3.4;
  
  
   default关键字:
  
   假设您不希望在堆棧为空时引
   发异常,而是希望返回堆栈中存储
   的类型的默认值
  
   值类型返回0
   引用类型返回null
  
  
   public T Pop()
{
m_StackPointer--;
if(m_StackPointer >= 0)
{
return m_Items[m_StackPointer];
}
else
{
m_StackPointer = 0;
throw new InvalidOperationException(
"Cannot pop an empty stack");
}
}


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

单个类型可以定义多个泛型

class Node<K,T>
{
public K Key;
public T Item;
public Node<K,T> NextNode;
public Node()
{
Key = default(K);
Item = defualt(T);
NextNode = null;
}
public Node(K key,T item,Node<K,T> nextNode)
{
Key = key;
Item = item;
NextNode = nextNode;
}
}
  
   public class LinkedList<K,T>
{
Node<K,T> m_Head;
public LinkedList()
{
m_Head = new Node<K,T>();
}
public void AddHead(K key,T item)
{
Node<K,T> newNode = new Node<K,T>
(key,item,m_Head.NextNode);
m_Head.NextNode = newNode;
}
}

泛型别名:

在文件头部使用using为特定类型取别名:
别名作用范围是整个文件

using List=LinkedList<int,string>;

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

  
   泛型约束:
  
   public class LinkedList<K,T>
{
T Find(K key)
{
Node<K,T> current = m_Head;
while(current.NextNode != null)
{
if(current.Key == key) //Will not compile
//因为编译器不知道K(实例化
//的实际类型)是否支持==运算
//符.例如默认情况下,结构
//不提供这样的实现
break;
else
current = current.NextNode;
}
return current.Item;
}
public T this[K key]
{
get{return Find(key);}
}
}
  
   LinkedList<int,string> list = new
   LinkedList<int,string>();
   list.AddHead(123,"AAA");
   list.AddHead(456,"BBB");
   string item = list[456];
   Debug.Assert(item == "BBB");
  
   T Find(K key)
{
Node<K,T> current = m_Head;
while(current.NextNode != null)
{
if(current.Key == key) //Will not compile
break;
else
current = current.NextNode;
}
return current.Item;
}
  
   泛型约束有三种
  
   <1>:派生约束:
用1:Where关键字 2:K:IComparable表示K只接受实现IComparable接口的类型,
尽管如此,还是无法避免传入值类型的K所带来的装箱问题.
System.Collections.Generic命名空间定义了泛型接口IComparable<T>:
public interface IComparable<T>
{
int CompareTo(T other);
bool Equals(T other);
}

避免装箱问题.

   public class LinkedList<K,T>where K:ICompamble
{
T Find(K key)
{
Node<K,T> current = m_Head;
while(current.NextNode != null)
{
if(current.Key.CompareTo(key)==0)
break;
else
current = current.NextNode;
}
return current.Item;
}
public T this[K key]
{
get{return Find(key);}
}
}
  
   C#从一个类继承,实现多个接口
  
   在C#2.0中,所有的派生约束必须放在类的实际派生列表之后,
   public class LinkedList<K,T>:IEnumberable<T> where K:IComparable<K>
   {...}
  
   通常,只须在需要的级别定义约束,
   比如:在Node节点定义IComparable<K>约束
   是没有意义的,如果一定要在Node上定义
   IComparable<K>约束,则LinkedList上也要
   定义此约束
  
   class Node<K,T> where K:IComparable<K>
   {...}
  
   public class LinedList<KeyType,DataType> where KeyType:IComparable<KeyType>
   {
Node<KeyType,DataType>m_Head;
   }
  
  
   一个泛型参数约束多个接口(彼些用逗号分隔)
  
public class LinkedList<K,T> where K : IComparable<K>,IConvertible
{...}
在一个约束中最多只能使用一个基类,这是因为C# 不支持实现的多重
继承
约束的基类不能是密封类或静态类,并且由编译器实施这一限制
不能将System.Delegate 或System.Array 约束为基类
可以同时约束一个基类以及一个或多个接口,但是该基类必须首先出
现在派生约束列表中
public class LinkedList<K,T> where K : MyBaseClass, IComparable<K>
{...}
  
  
   密封类:不能派生
  
   静态类:不能实例化
  
   自定义的接口或基类必须与泛型参数具有
   一致的可见性,
  
   正确的可见性:
   public class MyBaseClass
   {
   }
  
   interral class MySubClass<T> where T:MyBaseClass
   {
   }
  
   不正确的可见性:
    public class MyBaseClass
   {
   }
  
   interral class MySubClass<T> where T:MyBaseClass
   {
   }
  
   <2>:构造函数的约束:
  
    假设您要在一般类的内部实例化一个新的一般对象。问题在于,C#
编译器不知道客户端将使用的类型实参是否具有匹配的构造函数,因
而它将拒绝编译实例化行。
? 为了解决该问题,C# 允许约束一般类型参数,以使其必须支持公共
默认构造函数。这是使用new() 约束完成的。
class Node<K,T> where T : new()
{
public K Key;
public T Item;
public Node<K,T> NextNode;
public Node()
{
Key = default(K);
Item = new T();
NextNode = null;
}
}C#泛型          用MSN跟我交流
                                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值