C#集合与泛型
数组
- 数组是带索引的同类型对象的集合。
- 数组是一个对象,他们具有各种方法和属性。
int [] arr =new int[10];
——创建了一个System.Array的对象
–对于预定义类型,每个元素已经具有默认值。
–对于一般的自定义对象的数组,如MyClass.
public class C
{
public int i;
public C(int pi)
{
this.i = pi;
}
}
索引器
类似属性,可使用 get 和 set 访问器来定义索引器。
“它把实例数据分为更小的部分,并索引每个部分,获取或设置每个部分。”
public class FootBallTeam
{ string[] players;
public FootBallTeam()
{
players = new string[11];
}
public string this[int index]
{
get
{
if (index >= 0 && index < 11)
return players[index];
return "";
}
set
{
if (index >= 0 && index < 11)
players[index] = value;
}
}
}
this是必要的
可以在set或者get前增加private
集合类所支持的接口
先试看List类
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
n为了支持foreach语句,集合类必须实现IEnumerable 接口,该接口只包含一个方法 GetEnumerator
公用集合类
System.Collections
名字空间下:
- ArrayList——动态增长的数组
- Stack——堆栈
- Queue——队列FIFO
- SortedList——键值对集合,根据键值排序
- HashTable——键值对集合,根据键的哈希值组织
以上集合类存放的是“对象”
泛型形式更加常用
泛型
泛型类、泛型方法,常与集合或者集合相关方法使用
早期C#版本中,通过化是这样子的:
ArrayList list1 = new ArrayList();
list1.Add(3);
list1.Add(105);
ArrayList list2 = new ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");
也就是类型与通用基类Object直接进行强制转换
- 多次装箱拆箱影响性能
- 缺少编译时类型检查
泛型参数:
List<int> list1 = new List<int>();
list1.Add(3);
public class GenericList
在泛型类型或方法定义中,类型参数是客户端在实例化泛型类型的变量时指定的特定类型的占位符。
类型形参声明必须是标识符,不能是类型。
public class GenericList< int size>
C++中允许非类型的模板参数。
C++ 使用typename 或class 关键字
C# 中无需关键字。
C++中的非类型模板参数在类中可以当作常数使用,比如说定义数组
约束
约束就是用来约束泛型的,指限制泛型不用某种特殊类型参数
public class GenericList
泛型接口
为泛型集合定义接口
非泛型接口:
public interface IComparable// 非泛型接口
{
int CompareTo(object obj);
}
public class Person : IComparable {
double height;
public int CompareTo(object obj)
{
Person p = obj as Person; // 类型转换是很耗时的
if (this.height > p.height ) return 1;
else return -1;
}
}
泛型接口:
public interface IComparable<T>// 泛型接口
{
int CompareTo(T other);
}
public class Person : IComparable<Person> {
public double height;
public int CompareTo(Person other)
{
if (this.height > other.height) // 没有转换,快速
return 1;
else return -1;
}
}
泛型方法
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
只适用于泛型类成员
常用泛型类
System.Collections .Generic名称空间下:
- Stack<>
- Queue<>
- HashSet<>
- List<>
- Dictionary<>
List<>
表示可通过索引访问的对象的强类型列表。提供用于对列表进行搜索、排序和操作的方法。
Hashset<>
提供高性能的集合运算。集合是一组不重复出现且无特定顺序的元素.
无法排序的集合通过以下方式排序:
class Node
{
public int i;
public int j;
public Node( int pi,int pj)
{
i=pi;j=pj;
}
}
HashSet<Node> hs = new HashSet<Node>();
Random r = new Random();
for (int i = 0; i < 5; i++)
{
int temp= r.Next(100);
hs.Add(new Node(temp, temp*2));
}
foreach (Node n in hs) MessageBox.Show(n.i.ToString());
IEnumerable<Node> ie = hs.OrderBy(n => n.i);
foreach (Node n in ie) MessageBox.Show(n.i.ToString());
Dictionary< TKey, TValue>
提供了从一组键到一组值的映射。字典中的每个添加项都由一个值及其相关联的键组成。
泛型中的协变和逆变
- 协变:Covariance
–指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型,
- 逆变:Contravariance
–指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型。