6.1泛型类
6.1.1泛型类的定义
定义一个泛型类就是指的是,定义一个类,这个类中某些字段的类型是不确定的,这些类型可以在类构造的时候确定下来。
namespace c_sharp_001
{
class ClassA<T>
{
private T a;
private T b;
public ClassA(T a, T b)
{
this.a = a; this.b = b;
}
public string GetSum()
{
return a + " " + b;
}
}
}
6.1.2泛型方法
定义泛型方法就是定义一个方法,这个方法的参数的类型可以是不确定的,当调用这个方法的时候再去确定方法的参数的类型。
namespace c_sharp_001
{
class Program
{
public static string GetSum<T>(T a,T b)
{
return a + " " + b;
}
public static string GetD<T1,T2>(T1 a, T2 b)
{
return a + " " + b;
}
static void Main(string[] args)
{
Console.WriteLine(GetSum(12, 14));
Console.WriteLine(GetD<int,double>(12, 14.1));//声明多个类型,调用的时候需要指定
}
}
}
6.2集合类
6.2.1列表
1.列表的创建和使用
创建列表(列表可以存储任何类型的数据,在创建列表对象的时候首先要指定你要创建的这个列表要存储什么类型的)(泛型)。
List<int> scoreList = new List<int>();
new List<int>(){1,2,3}
new List<string>(){"one","two"}
var scoreList = new List<int>();
往列表中插入数据:
scoreList.Add(12);
scoreList.Add(45);
如何取得列表中的数据?列表中的数据跟数组有点相似,索引从0开始 ,可以通过索引来访问。
scoreList[0] //访问添加到列表中的第一个数据
namespace c_sharp_001
{
class Program
{
static void Main(string[] args)
{
List<int> scoreList1 = new List<int>();//正常创建空列表
var scoreList = new List<int>();//匿名类型创建空列表,常用
var scoreList2 = new List<int>() { 1, 2, 3 };//创建列表并赋初值
scoreList.Add(12);//向列表中插入数据
Console.WriteLine(scoreList[0]);//通过索引访问列表数据
Console.ReadKey();
}
}
}
列表内部数据是使用数组进行的存储,一个空的列表内部会有一个长度为0的数组,当给列表中添加元素的时候,列表的容量会扩大为4,如果添加第5个的时候,列表的大小会重新设置为8,如果添加第9个元素,列表容量会扩大为16,依次增加。当列表的中的容量发生改变的时候,它会创建一个新的数组,使用Array.Copy()方法将旧数组中的元素复制到新数组中。为了节省时间,如果事先知道要存储的数据的个数,就可以利用列表的构造函数指定列表的容量大小,比如下面的:
List<int> intlist = new List<int>(10);
创建了一个初始容量为10的列表,当容量不够用的时候,每次都会按照原来容量的2倍进行扩容。
我们可以通过Capacity属性获取和设置容量:
intList.Capacity = 100;
注意容量和列表中元素个数的区别,容量是列表中用于存储数据的数组的长度通过Capacity获取,列表中的元素是我们添加进去需要管理的数据,通过Count获取。
2.列表的遍历for与foreach
namespace c_sharp_001
{
class Program
{
static void Main(string[] args)
{
var scoreList = new List<int>();
scoreList.Add(1);
scoreList.Add(2);
scoreList.Add(3);
for (int i = 0; i < scoreList.Count; i++)//遍历所有的索引,通过索引访问列表中的元素
{
Console.WriteLine(scoreList[i]);
}
foreach(var temp in scoreList)//依次取得list中的每一个元素赋值给temp并执行循环体
{
Console.WriteLine(temp);
}
Console.ReadKey();
}
}
}
3.操作列表的属性和方法
属性和方法 | 作用 |
Capacity | 获取容量大小 |
Add() | 添加元素 |
Insert(int index,int item) | 插入元素 |
[index] | 访问元素 |
Count | 访问元素个数 |
RemoveAt(int index) | 移除指定位置的元素 |
IndexOf() | 取得一个元素所在列表中的索引位置从前往后搜索,搜索到满足条件的就停止方法返回该元素的索引,如果没有找到指定元素就返回-1 |
LastIndexOf() | 取得一个元素所在列表中的索引位置从后往前搜索,搜索到满足条件的就停止方法返回该元素的索引,如果没有找到指定元素就返回-1 |
Sort() | 对列表中是元素进行从小到大排序 |
4.创建一个列表
namespace c_sharp_001
{
class MyList<T> where T: IComparable//T继承自IComparable,是可比较的???
{
private T[] array;
private int count=0;//当前添加的元素个数
public MyList(int size)
{
if (size > 0)
{
array = new T[size];
}
}
public MyList()
{
array = new T[0];
}
public int Capacity
{
get{ return array.Length; }
}
public int Count
{
get { return count; }
}
public void Add(T item)
{
if (Count == Capacity)//当前元素个数是否达到数组容量
{
if (Capacity == 0)
{
array = new T[4];
}
else
{
var newArray = new T[Capacity * 2];//数组容量扩大2倍
Array.Copy(array, newArray, Count);//旧数组数据传递给新数组
array = newArray;//新数组引用传给旧数组,旧数组内存清除
}
}
array[Count] = item;//0~Count-1索引已有元素,从Count开始添加
count++;//元素个数自增
}
public T GetItem(int index)
{
if (index >= 0 && index <= Count - 1)
{
return array[index];
}
else
{
//Console.WriteLine("索引超出范围");
throw new Exception("索引超出范围");//抛出异常
}
}
public T this[int index]//索引器
{
get//通过索引器取值调用get块
{
return GetItem(index);
}
set//通过索引器设置调用set块
{
if (index >= 0 && index <= Count - 1)
{
array[index] = value;
}
else
{
throw new Exception("索引超出范围");//抛出异常
}
}
}
public void Insert(int index,T item)
{
if (index >= 0 && index <= Count - 1)
{
if (Count == Capacity)
{
var newArray = new T[Capacity * 2];//数组容量扩大2倍
Array.Copy(array, newArray, Count);//旧数组数据传递给新数组
array = newArray;//新数组引用传给旧数组,旧数组内存清除
}
for(int i = Count - 1; i <= index; i--)//从后向前(插入位置)遍历
{
array[i + 1] = array[i];//将插入位置之后的元素向后移一位
}
array[index] = item;
count++;
}
else
{
throw new Exception("索引超出范围");
}
}
public void RemoveAt(int index)
{
if (index >= 0 && index <= Count - 1)
{
for(int i = index + 1; i < Count; i++)
{
array[i - 1] = array[i];
}
count--;
}
else
{
throw new Exception("索引超出范围");//抛出异常
}
}
public int IndexOf(T item)
{
for(int i = 0; i < Count; i++)
{
if (array[i].Equals(item))
{
return i;
}
}
return -1;
}
public int LastIndexOf(T item)
{
for (int i = Count-1; i >=0; i--)
{
if (array[i].Equals(item))
{
return i;
}
}
return -1;
}
public void Sort()
{
for (int j = 0; j < count - 1; j++)
{
for (int i = 0; i < count - 1 - j; i++)
{
if (array[i].CompareTo(array[i + 1]) > 0)
{
T temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
}
}
}
}
}
namespace c_sharp_001
{
class Program
{
static void Main(string[] args)
{
var myList = new MyList<int>();
for(int i = 0; i < 8; i++)
{
myList.Add(i);//Add方法设置值
}
myList[7] = 100;//索引器设置
myList.Insert(1, 20);
myList.RemoveAt(1);
for(int i = 0; i < myList.Count; i++)
{
//Console.WriteLine(myList.GetItem(i));
Console.WriteLine(myList[i]);
}
myList.Sort();
Console.WriteLine();
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
Console.WriteLine("数组大小:"+myList.Capacity);
Console.ReadKey();
}
}
}