第2章:泛型


本章目标

  1. 理解泛型的概念

  2. 掌握泛型方法的定义与使用

  3. 掌握泛型类的定义与使用

  4. 掌握泛型接口的定义与使用

本章内容

泛型的概念

​ 泛型(generic)是C# 2.0推出的新语法,并不是语法糖,它是专门为处理多段代码在不同的数据类型上执行相同的指令的情况而设计的。 即泛型让不同的数据类型支持相同的业务逻辑。

​ 泛型是一个复合类型,把多个类型混合一起作用, 在C#中应用比较广的泛型:泛型方法,泛型类,泛型接口

泛型方法

泛型方法:调用时泛型参数类型可以省略

泛型定义时,是延迟声明的:即定义的时候没有指定具体的参数类型,把参数类型的声明推迟到了调用的时候才指定参数类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/// <summary>
/// 泛型方法
/// 求和
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t1"></param>
/// <param name="t2"></param>
/// <returns></returns>
static object Fun1<T>(T t1,T t2)
{
return Convert.ToDouble(t1) + Convert.ToDouble(t2);
}

/// <summary>
/// 泛型方法
/// 比较大小
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t1"></param>
/// <param name="t2"></param>
/// <returns></returns>
static T Fun2<T>(T t1, T t2)
{
double n1 = Convert.ToDouble(t1);
double n2 = Convert.ToDouble(t2);

return n1 > n2 ? t1 : t2;
}
1
2
3
4
5
6
7
#region 测试泛型方法
Fun1(23, 15);
Fun1<int>(23, 15);

Fun2(23.5, 18.9);
Fun2<double>(23.5, 18.9);
#endregion

泛型类

泛型类定义:在类名后

泛型类的作用域:整个类中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/// <summary>
/// 泛型类
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyArray<T>
{
T[] data;
int size;

public int Size { get => size; set => size = value; }

public MyArray(){
this.data=new T[10];
}

/// <summary>
/// 添加
/// </summary>
/// <param name="item"></param>
public void Add(T item)
{
//栈满扩容
if (this.data.Length==this.Size)
{
this.AutoExpand();
}

this.data[Size++] = item;
}

/// <summary>
/// 索引器
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this[int index]
{
get
{
return this.data[index];
}
set
{
this.data[index] = value;
}
}

/// <summary>
/// 自动扩容
/// </summary>
private void AutoExpand()
{
T[] newData = new T[this.data.Length*2];
for (int i = 0; i < this.data.Length; i++)
{
newData[i] = this.data[i];
}

this.data = newData;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#region 测试泛型类

MyArray<int> myArray = new MyArray<int>();
myArray.Add(13);
myArray.Add(24);
myArray.Add(55);

myArray[1] = 100;

for (int i = 0; i < myArray.Size; i++)
{
Console.WriteLine(myArray[i]);
}

#endregion

泛型接口

泛型接口和泛型类定义方式一样,在接口名称后使用未知类型

只是方法签名,没有方法体,默认是公开的,不能添加修改符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/// <summary>
/// 泛型接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface MyInterface<T>
{
void Service(T t1, T t2);
}

/// <summary>
/// 实现泛型接口的类
/// </summary>
public class MyClass1 : MyInterface<double>
{
public void Service(double t1, double t2)
{
Console.WriteLine(t1+ t2);

}
}

/// <summary>
/// 实现泛型接口的类
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyClass2<T> : MyInterface<T>
{
public void Service(T t1, T t2)
{
Console.WriteLine(Convert.ToDouble(t1)+Convert.ToDouble(t2));

}
}
1
2
3
4
5
6
7
8
9
#region 测试泛型接口

MyInterface<double> my1 = new MyClass1();
MyInterface<int> my2 = new MyClass2<int>();

my1.Service(2.3, 4.5);
my2.Service(23,45);

#endregion

本章总结

课后作业

1.在指定索引位置插入数据
1.检查索引的有效性
2.将索引位置到最后一个位置的所有元素向后平移一位(从最后一个元素开始)
3.将新数据插入到指定索引的位置
4.更新容器大小
2.移除首个元素
1.检查容器是否为空
2.将所以为1到末尾的所有元素向前平移一位(从索引为1的元素开始)
3.末尾清空
4.更新容器大小
3.移除尾个元素
1.检查容器是否为空
2.清空末尾
3.更新容器大小
4.移除指定索引的元素
1.检查索引的有效性
2.判断首尾元素,调用相应方法完成
3.将索引其后的所有元素向前平移一位
4.末尾清空
5.更新容器大小

5:泛型接口应用
1.定义泛型接口 IValidate<T>,包含数据验证的方法Check(T item);
2.定义实现类:
CheckName类实现接口,完成验证。(2-6个字)
CheckAge类实现接口,完成验证。(1-120)
CheckSex类实现接口,完成验证。(男或女)
3.编写测试类,完成验证功能
public bool CheckData( IValidate interface,T data){