知识来源:1-最新2021C#.NET5--语法之泛型_哔哩哔哩_bilibili
一、泛型的引入
using System.Collections;
// -- 1、常规的定义 具体类型 数组的语法
// 每个类型的数组只能传入对应类型的元素,使用不过灵活
int[] sum1 = new int[2];
int[] sum2 = new int[] {};
double[] sum3 = new double[3];
// -- 2、ArrayList可以传入任何数据类型元素,解决了常规数组不灵活问题(代码重用)
// ArrayList当前接近被淘汰
// Add方法的类型是Object类型,缺点:类型不安全、效率低(频繁拆装箱操作)
ArrayList arrayList = new ArrayList();
arrayList.Add(1);
arrayList.Add("Test");
二、泛型特点
// -- 3、泛型
/*
T:type,表示泛型
泛型:带有'<>'符号的都是泛型
优点:代码重用、类型安全、高效率
分类:预定义(List<T>,Dictionary<TKey, TValue>)、自定义,
延迟声明:定义的时候就是一个站位符,使用的时候一定确定具体类型。
*/
List<int> ints = new List<int>();
Dictionary<int, string> dictionary = new Dictionary<int, string>();
三、自定义泛型方法
// -- 4、自定义泛型方法
Student student = new Student() { Name = "张三" };
// ---
Show1(1); // 传入值是:1,参数类型是:Int32
Show1("Test"); // 传入值是:Test,参数类型是:String
Show1(student); // 传入值是:Student { Name = 张三 },参数类型是:Student
// ---
Console.WriteLine(Show2<Student>()); // null
Console.WriteLine(Show2<int>()); // 0
// ---
Console.WriteLine(Show3<Student>()); // null
Console.WriteLine(Show3<int>()); // 0
// 泛型参数
static void Show1<T>(T value)
{
Console.WriteLine($"传入值是:{value},参数类型是:{value.GetType().Name}");
}
// 泛型返回值
static T Show2<T>()
{
//值类型不能为nu11,引用类型可以
//default,如果是引用类型 那就返回nu11,如果是值类型就返回0
return default(T);
}
// 泛型局部变量
static T Show3<T>()
{
T value = default(T);
return value;
}
// 测试类
record Student
{
public string Name { get; set; }
}
四、自定义泛型类
// -- 5、自定义泛型类
MyList<int> myList = new MyList<int>();
class MyList<T>
{
private MyList<T> _list;
public void Add(T item)
{
_list.Add(item);
}
}
五、泛型约束
1、对于泛型方法,如果在方法内直接声明一个泛型变量并对其赋值null,或者赋值0,此时都会报错
2、类型约束,引用类型的约束:where T:class
,确保泛型类型参数T必须是引用类型。
-
且此时调用Test<T>方法,这个T只能为引用类型,否则报错
3、类型约束,值类型约束:where T:struct
,确保泛型类型参数T必须是值类型
4、构造函数约束where T:new()
,确保泛型类型参数T必须具有无参构造函数
-
值类型都有一个隐式的公共无参数构造方法,所以
Test<int>()
没报错
多个约束同时存在时,构造函数约束要放在最后
-
构造函数约束 不能和 值类型约束一起使用
5、接口约束where T : IDisposable
,确保泛型类型参数T必须实现IDisposable接口。
6、自定义约束where T : 自定义类or自定义接口
-
多个约束时,自定义约束要在最前面、只能有一个自定义约束
-
接口约束同时可以有多个
7、可以对多个参数分别做约束