4.1 泛型概述
4.1.1 泛型的概念
- 泛型是程序设计语言的一种特性,其允许程序员在强类型程序设计语言中编写代码时定义一些可变部分
- 泛型为使用 C# 编写面向对象程序增加了极大的效率和灵活性。它不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换,所以性能得到了提高
- 泛型类和泛型方法同时具备可重用性、类型安全性和高效性,这是非泛型类和非泛型方法无法具备的优点。泛型通常用于集合以及作用于集合的方法。
4.1.2泛型的优点
下面将以生活中的邮政编码表示为例进行讲解
示例:
public class Coding<T>
{
private T postcode;
public T Postcode
{
get { return postcode; }
set { postcode = value; }
}
public void Println()
{
Console.WriteLine(String.Format(“ 当前输入的数据类 型是 :{0},值是 :{1}", typeof(T), postcode));
}
}
static void Main(string[] args)
{
Coding<string> typeString = new Coding<string>();
typeString.Postcode = "430070";
typeString.Println();
Coding<int> typeInt = new Coding<int>();
typeInt.Postcode = 430070;
typeInt.Println();
}
4.2 泛型集合 List<T>
4.2.1泛型集合类 List<T> 介绍
- 泛 型 最 常 见 的 用 途 是 创 建 集 合 类。.NET Framework 类 库 提 供 了 一 个 新 的 命 名 空 间 System.Collections.Generic,其中包含几个基于泛型的新的集合类
- 向 ArrayList 类型的集合中添加元素时,元素会隐式强制转换为 object 类型,这会造成编译时缺少类型安全,引发错误
- 使用List<T>集合试类型检查在编译时进行而不是在运行时进行,其性能则会增强。编译时类型安全可使应用程序代码更加清晰
4.2.2 ArrayList 类型不安全性
- List<T> 与 ArrayList 的使用方式完全一样,唯一的区别在于定义时必须指定集合中存储数据的类型,增强了类型的安全性
示例:
static void Main(string[] args)
{
int num = 1;
ArrayList custList = new ArrayList();
Customer jun = new Customer(" 李军 ", 32, " 广州 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州 ");
custList.Add(jun);
custList.Add(yun);
custList.Add(" 雷斯 ");
Console.WriteLine(" 排队的客户有:");
foreach (object obj in custList)
{
Customer cust = obj as Customer;
Console.WriteLine("{0} 号客户:{1}", num++, cust.Name);
}
}
4.2.3 List<T> 的使用
使用List<T>泛型集合实现上述功能
示例:
static void Main(string[] args)
{
int num = 1;
List<Customer> custList = new List<Customer>();
Customer jun = new Customer(" 李军 ", 32, " 广州 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州 ");
custList.Add(jun);
custList.Add(yun);
custList.Add(" 雷斯 ");
Console.WriteLine(" 排队的客户有:");
foreach (Customer cust in custList)
{
Console.WriteLine("{0} 号客户:{1}", num++, cust.Name);
}
}
List<T>的常用属性
- Capacity :获取或设置 List<T> 中可包含的元素个数
- Count :获取 List<T> 中实际包含的元素个数
ArrayList的常用方法
- Add() :将元素添加到 List<T> 的结尾处
- Insert() :将元素添加到 List<T> 的指定索引处
- Remove() :移除 List<T> 中指定的元素
- RemoveAt():移除 List<T> 中指定索引处的元素
- Clear():清除 List<T> 中所有的元素
- Sort():对 List<T> 中的元素排序
- Reverse():将 List<T> 中的元素顺序反转
- ToArray():将 List<T> 中的元素复制到数组中
在实际应用中,很多场合都需要使用 List<T> 集合
//定义商品类
class Goods{
private string name; // 商品名称
private double price; // 商品价格
private string description; // 商品描述
public Goods(string name, int price, string description)
{
this.Name = name;
this.Price = price;
this.Description = description;
}
//字段封装代码省略…
}
//定义购物车类
class ShoppingCart
{
public ShoppingCart()
{
this.ShoppingList = new List<Goods>();
}
private List<Goods> ShoppingList;
}
//在购物车类中编写查看商品和添加商品的方法
class ShoppingCart
{
public void Show()
{
Console.WriteLine(" 已放入购物车商品如下:");
Console.WriteLine(" 商品名称 \t\t 价格 ");
Console.WriteLine("=======================");
foreach (Goods goods in this.ShoppingList)
{
Console.WriteLine("{0}\t\t{1}", goods.Name, goods.Price);
}
}
public void Add(Goods goods)
{
this.ShoppingList.Add(goods);
Console.WriteLine(" 把 {0} 放入了购物车 ", goods.Name);
}
}
//模拟购物过程
static void Main(string[] args)
{
Goods bag = new Goods(" 鳄鱼钱包 ", 12000, " 全球限量发售 500 个。");
Goods boots = new Goods(" 雪地靴 ",680, " 就算在雪地里也有走在炭火上的感觉。");
Goods phone = new Goods(" 王牌手机 ", 1480, " 在火星也能打电话回家。");
ShoppingCart cart = new ShoppingCart();
cart.Add(bag);
cart.Add(phone);
cart.Show();
}
从购物车中移除商品
//集合和数组相互转换
static void Main(string[] args)
{
//初始化集合省略…
Console.WriteLine("========= 集合转换为数组 =============");
string[] array = list.ToArray();
foreach (string item in array)
{
Console.WriteLine(item);
}
Console.WriteLine("========= 数组转换为集合 =============");
List<string> goodsList = new List<string>(array);
foreach (string item in goodsList)
{
Console.WriteLine(item);
}
}
4.3 泛型字典集合 Dictionary<K,V>
4.3.1泛型字典集合 Dictionary<K,V> 介绍
- 泛型字典集合 Dictionary<K,V> 与 List<T> 一样,与 Hashtable 集合的使用方式大体一样,唯一的区别在于定义时必须指定 key 和 value 的数据类型,这样做会增强类型的安全性
- Dictionary<K,V> 的常用属性
- Keys :获取包含 Dictionary<K,V>中所有键的 ICollection
- Values:获取包含 Dictionary<K,V>中所有值的 ICollection
- Count:获取 Dictionary<K,V>中键/值对的数目
- Dictionary<K,V> 的常用方法
- Add(object key, object value):将带有指定键和值的元素添加到 Dictionary<K,V>中
- Remove(object key):从 Dictionary<K,V>中移除带有指定键的元素
- Clear():移除 Dictionary<K,V>中所有元素
- ContainsKey(object key):确定 Dictionary<K,V>中是否包含指定键
- ContainsValue(object value):确定 Dictionary<K,V>中是否包含指定值
4.3.2 Dictionary<K,V> 的使用
使用 Dictionary<K,V> 替换 List<T>,使购物车可以同时保存商品名和商品数量
示例:
class ShoppingCart
{
//定义商品集合,商品名存为 key,数量存为 value
public ShoppingCart()
{
this.ShoppingList = new Dictionary<Goods, int>();
}
private Dictionary<Goods, int> ShoppingList;
}
修改查看购物车方法和添加商品方法
示例:
public void Show()
{
Console.WriteLine(" 已放入购物车商品如下:");
Console.WriteLine(" 商品名称 \t\t 价格 \t\t 数量 ");
Console.WriteLine("=================================================");
foreach (Goods goods in this.ShoppingList.Keys)
{
Console.WriteLine("{0}\t\t{1}\t\t{2}", goods.Name, goods.Price, this.ShoppingList[goods]);
}
}
public void Add(Goods goods, int number)
{
this.ShoppingList.Add(goods, number);
Console.WriteLine(" 把 {0} 件 {1} 放入了购物车 ",number, goods.Name);
}
修改移除商品方法
public void Remove(Goods goods, int number)
{
if (this.ShoppingList.ContainsKey(goods))
{
if (this.ShoppingList[goods] > number)
{
this.ShoppingList[goods] -= number;
}
else
{
this.ShoppingList.Remove(goods);
}
Console.WriteLine(" 从购物车中移除了 {0} 件 {1}", number, goods.Name);
}
}
模拟购物过程
static void Main(string[] args)
{
Goods bag = new Goods(" 鳄鱼钱包 ", 12000, " 全球限量发售 500 个。");
Goods boots = new Goods(" 雪地靴 ", 680, " 就算在雪地里也有走在炭火上的感觉。");
Goods phone = new Goods(" 王牌手机 ", 1480, " 在火星也能打电话回家。");
ShoppingCart cart = new ShoppingCart();
cart.Add(bag,2);
cart.Add(phone,3);
cart.Show();
cart.Remove(bag,1);
cart.Show();
cart.Remove(bag, 1);
cart.Show();
}
总结
- 使用泛型类型可以极大限度重用代码、保护类型的安全及提高程序性能
- 泛型集合可以约束存储对象有的类型,在访问集合中的元素时无须进行类型转换
- List<T>与ArrayList的使用方式完全一样,唯一的区别在于定义时必须指定集合中存储数据的类型,增强了类型的安全性
- 泛型集合Dictionary<K,V>与Hashtable的使用方式完全一样,唯一的区别在于定义时必须指定Key和Value的数据类型,同样也增强了类型的安全性