C#list删除另外list⾥⾯的元素_【⾃学C#】笔记22泛型
⼀、泛型简介
泛型是 C#2.0 推出的新语法,不是语法糖,⽽是 2.0 由框架升级提供的功能。
我们在编程程序时,经常会遇到功能⾮常相似的模块,只是它们处理的数据不⼀样。
但我们没有办法,只能分别写多个⽅法来处理不同的数据类型。
这个时候,那么问题来了,有没有⼀种办法,⽤同⼀个⽅法来处理传⼊不同种类型参数的办法呢?泛型的出现就是专门来解决这个问题的。
泛型是在 System.Collections.Generic 命名空间中的,⽤于约束类或⽅法中的参数类型。
泛型的应⽤⾮常⼴泛,包括⽅法、类以及集合等。
在前⾯已经介绍了类和⽅法的定义,那么泛型究竟有什么作⽤呢?在前⾯《C#集合》⼀节中介绍了集合,集合中的项允许是 object 型的值,因此可以存放任意类型的值。
(总之,就是让⼀个类似集合的数据,可以存储不同类型的数据。)
(换句话说,就是把不同类型的数据,存储进⼀个“集合”中。)
1.例
在 ArrayList 中以 double 类型存⼊学⽣考试成绩,但存⼊值时并没有做验证,存⼊了其他数据类型的值,代码如下。
ArrayList arrayList=new ArrayList();arrayList.Add(100);arrayList.Add("abc");arrayList.Add(85.5);
在输出集合中的元素时,如果使⽤ double 类型来遍历集合中的元素,代码如下。
foreach (int d in arrayList){ Console.WriteLine(d);}
分析:
会报错!因为数据内的类型并不统⼀。
执⾏上⾯的代码,由于在集合中存放的并不全是 double 类型的值,因此会出现 System.InvalidCastException 异常,即指定的转换⽆效。
为了避免类似的情况产⽣,将集合中元素的类型都指定为 double 类型,不能在集合中输⼊其他类型的值,这种设置⽅式即为泛型的⼀种应⽤。
⼆、可空类型:Nullable
对于引⽤类型的变量来说,如果未对其赋值,在默认情况下是 Null 值。
对于值类型的变量,如果未赋值,整型变量的默认值为 0。
但通过 0 判断该变量是否赋值了是不太准确的。
在 C# 语⾔中提供了⼀种泛型类型(即可空类型 (System.Nullable))来解决值类型的变量在未赋值的情况下允许为 Null 的情况。
定义可空类型变量的语法形式如下。
System.Nullable<T> 变量名;
其中,
Nullable所在的命名空间 System 在 C# 类⽂件中默认是直接引⼊的。
因此可以省略 System,直接使⽤ Nullable 即可;
T 代表任意类型,例如定义⼀个存放 int 类型值的变量,代码如下。
Nullable<int> a;
除了使⽤上⾯的⽅法定义可空类型变量以外,还可以通过如下语句定义⼀个 int 类型的可空类型变量。
int? a
从上⾯的定义可以看出,int? 等同于Nullable。
此外,在使⽤可空类型时也可以通过 HasValue 属性判断变量值是否为 Null 值。
1.例
下⾯通过实例来演⽰可空类型的应⽤。
分别创建⼀个 int 的可空类型变量和 double 的可空类型变量,并使⽤ HasValue 属性判断其值是否为空。
根据题⽬要求,代码如下。
class Program{ static void Main(string[] args) { int? i = null; double? d = 3.14; if (i.HasValue) { Console.WriteLine("i 的值为{0}", i); 分析:
定义⼀个存放 int 类型值的变量i=null。
定义⼀个存放 double 类型值的变量d=3.14。
然后通过 HasValue 属性,判断变量值是否为 Null 值。
运⾏结果:
从上⾯的执⾏效果可以看出,可空类型允许将值类型变量的值设置为 Null,并可以通过 HasValue 属性判断其是否为 Null 值。
三、泛型⽅法的定义及使⽤
在 C# 语⾔中泛型⽅法是指通过泛型来约束⽅法中的参数类型,也可以理解为对数据类型设置了参数。如果没有泛型,每次⽅法中的参
数类型都是固定的,不能随意更改。
在使⽤泛型后,⽅法中的数据类型则有指定的泛型来约束,即可以根据提供的泛型来传递不同类型的参数。
定义泛型⽅法需要在⽅法名和参数列表之间加上<>,并在其中使⽤ T 来代表参数类型。
当然,也可以使⽤其他的标识符来代替参数类型, 但通常都使⽤ T 来表⽰。下⾯通过实例来演⽰泛型⽅法的使⽤。
(总之就是能让参数类型变得灵活。)
1.例
创建泛型⽅法,实现对两个数的求和运算。
class Program{ static void Main(string[] args) { //将T设置为double类型 Add<double>(3.3, 4); //将T设置为int类型 Add<int>(3, 4); } //加法运分析:
⾸先是11~15⾏,⾃定义的⼀个泛型⽅法函数。
还是个静态的,⽅便直接调⽤。
通过⽅法可以看到,除了正常的⽅法名外,多了这个。program可以删除吗
T可以理解成⼀种“代替传参”,就像数学代数中,不知具体数字的情况下,就⽤x代替。再或者在不知具体要重复多少次时,⼈们就
喜欢说重复了n次。
总之,将T理解成⼀个虚拟的数据类型,并且还是那种随时都能被替换掉的代号,以便使⽤调⽤时,改变数据类型。
⽅法内部,是⼀个double类型的数据,并且还通过.Parse()⽅法,将获取的字符串数据,都强制转换成double类型。
因为参数是⼀个字符串,所以还需要通过.ToString()⽅法,强⾏转成字符串类型。
6⾏和8⾏
因为是静态⽅法,所以可以直接被调⽤。
也就将T替换成其他数据类型,并使⽤。
运⾏结果:
从上⾯的执⾏效果可以看出,在调⽤ Add ⽅法时能指定不同的参数类型执⾏加法运算。
如果在调⽤ Add ⽅法时,没有按照 中规定的类型传递参数,则会出现编译错误,这样就可以尽量避免程序在运⾏时出现异常。
四、泛型类的定义及使⽤
C#语⾔中泛型类的定义与泛型⽅法类似,是在泛型类的名称后⾯加上,当然,也可以定义多个类型,即
“”。
表达形式:
class 类名
{
//类的成员
}
例
class A{ public T[] items = new T[3];}
这样,在类的成员中即可使⽤ T1、T2 等类型来定义。
1.例
定义泛型类,并在泛型类中定义数组,提供添加和显⽰数组中全部元素的 ⽅法。
class MyTest{ private T[] items = new T[3]; private int index = 0; //向数组中添加项 public void Add(T t){ if (index < 3) { items[index] = t; 在 Main ⽅法中调⽤ MyTest 类中的⽅法,代码如下。
class Program{ static void Main(string[] args) { MyTest<int> test = new MyTest<int>(); test.Add(10); test.Add(20); test.Add(30); test.Sho 分析:
⾸先是泛型类MyTest。
先定义了⼀个私有变量泛型数组items。
⼜定义了⼀个私有变量index,int类型。
⼜定义了⼀个泛型⽅法,⽤于往泛型数组中添加值。
⼜定义了⼀个遍历items的⽅法。
然后是调⽤。
⾸先是创建了⼀个泛型的实例,并把T换成了int类型。
然后追加数据,就是泛型类种的Add⽅法。
最后就是输出打印,就是Show⽅法。
运⾏结果:
从上⾯的执⾏效果可以看出,根据泛型类中指定的数据类型创建数组,并实现了对数组元素的添加和显⽰。
五、泛型集合定义及使⽤
C# 语⾔中泛型集合是泛型中最常见的应⽤,主要⽤于约束集合中存放的元素。
由于在集合中能存放任意类型的值,在取值时经常会遇到数据类型转换异常的情况,因此推荐在定义集合时使⽤泛型集合。
前⾯《C# ArrayList》与《C# Hashtable》中已经介绍了⾮泛型集合中的 ArrayList、Hashtable。
⾮泛型集合中的 ArrayList、Hashtable 在泛型集合中分别使⽤ List 和 Dictionary 来表⽰,其他泛型集合均与⾮泛型集合⼀致。
下⾯以 List 和 Dictionary 为例介绍泛型集合的使⽤。
总之,有是⼀种新类型,⼀种新⽤法。
1.例
使⽤泛型集合 List 实现对学⽣信息的添加和遍历。
根据题⽬要求,将学⽣信息定义为⼀个类,并在该类中定义学号、姓名、年龄属性。
在泛型集合 List 中添加学⽣信息类的对象,并遍历该集合。实现的代码如下。
using System.Collections.Generic;class Program{ static void Main(string[] args) { //定义泛型集合 List list = new List(); //向集合中存⼊3名学员
注意:
需要追加using System.Collections.Generic;
分析:
⾸先是第18⾏~38⾏。
⾃定义了⼀个Student类,这⾥跟泛型没关系,正常的类。
并进⾏了构造⽅法,⽅便创建类的同时,直接赋值。
然后是第1~17⾏。
定义了⼀个Student数据类型的泛型。
这是系统已经编辑好的泛型类,并且Add()⽅法也都集成在了⾥⾯。
所以直接通过Add()⽅法进⾏追加数据。
⽽这⾥每个数据,就不再是简单的数字和字符串数据了,⽽是⼀个⼤型的类数据。
然后就是遍历输出集合中的元素。
运⾏结果
从上⾯的执⾏效果可以看出,在该泛型集合中存放的是 Student 类的对象,当从集合中取岀元素时并不需要将集合中元素的类型转换为
Student 类的类型,⽽是直接遍历集合中的元素即可,这也是泛型集合的⼀个特点。
总之,因为类的类型各种各样,有了泛型这种⽅式,明显省去了⼀⼀修改参数的数据类型。或者定义相同的功能,但数据类型不同的类。
2.例
使⽤泛型集合 Dictionary 实现学⽣信息的添加,并能够按照学号查询学⽣信息。
根据题⽬要求,将在实例 1 中所创建学⽣信息类的对象作为 Dictionary 集合中的 value 值部分,key 值部分使⽤学⽣信息类中的学
号,这样能很容易地通过学号查询学⽣的信息。实现的代码如下。
class Program{ static void Main(string[] args) { Dictionary<int, Student> dictionary = new Dictionary<int, Student>(); Student stu1 = new Student(1, "⼩分析:
这是另⼀种泛型,也就是多参数的泛型。
系统同样都已经写好,只会导⼊包后就能直接使⽤。
这就是所谓的⾯向对象编程,听起来很⾼⼤上,实际也就这么回事。
⾸先是定义了⼀个int和student两个类型的泛型变量dictionary。
然后是定义了三个student类的实例,并直接赋值传参。
再然后就是把student类的实例中的数据调取出来,并往泛型中赋值。
这⾥因为有int和student两个数据类型,所以Add()⽅法中,第⼀个参数必须是int类型,⽽第⼆个参数也必须是student类的数据类
型。
运⾏结果
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论