C# 里的泛型如何使用?

答:泛型是 C# 2.0 开始引入的一种更加灵活、规范的数据操作机制,看例子:

class Student{}

假设有学生对象需要存入集合,再提取出来

ArrayList list = new ArrayList(); //1、实例化 list 集合对象

Student s = new
Student();        //2、实例化一个学生对象

list.Add(s);                     
//3、将学生存入集合

Student tmp = (Student)
list[0];  //4、将学生对象从集合中取出来

传统的操作方式如上。

如果,存入的是学生对象,而取出的时候错以为是老师对象,第 4 行代码可能写成:

Teacher tmp = (Teacher) list[0];

在编译时,系统不会发现这个问题,因为存入 list 的对象都会被装箱为 object ,取出的时候由 object
进行拆箱,系统没办法确定数据类型,所以,就算存入和取出的类型不一致,也不会提示错误。编译不出错,运行时肯定要出错了,因为学生对象强制转换为老师,是错误的。

那如何尽早的进行类型规范和检查呢?使用泛型。

List<Student> list = new
List<Student>();          
//1、实例化只能存放 Student 对象的集合

Student s = new
Student();        //2、实例化一个学生对象

list.Add(s);                     
//3、将学生存入集合

Student tmp =
list[0];           
//4、将学生对象从集合中取出来

注意代码的区别:

第一行:我们没有再使用 ArrayList ,而是使用了 List 泛型集合

语法:尖括号
< > 中的数据类型是在规范集合只能存入此类型数据。

第四行:因为定义时有固定的操作类型(),所以,提取 list[0] 肯定是 Student
类型的对象,免去了数据类型转换的麻烦。

那我们再使用 Teacher tmp = list[0];
去进行错误类型的提取,程序将在编译时发现数据类型和泛型定义不一致的错误,使我们的程序更安全,更规范,同时,进出 list
集合的数据都有了类型,免去了传统集合进出数据时的装箱和拆箱的操作,提高了数据访问速度。

泛型可以更规范的定义集合中存储的数据类型,其实可以以一种模板的方式来理解:

List<Student> list = new List<Student>();
相当于系统原有 List 集合类型是模板,我们通过模板创建了一种只能操作 Student 类型的集合。那模板的操作方式还有什么用途呢?

现在我们调用 list.Sort() 方法,对集合当中的学生对象进行排序,因为 Student
类型不是系统内置的数据类型,所以排序操作肯定是错误的。那如果需要按照我们的要求进行排序,比如按年龄排序,又该怎么做呢?

很多集合都需要有排序功能,所以系统有接口 IComparable ,来规范对象排序的操作。既然
IComparable 可以规范各种类型的排序,那就认为是一种模板,同时也就想到了泛型:

class Student : IComparable<Student> //实现 泛型
比较接口

{

private int _age;

public int Age { get ; set;
}  //定义年龄属性

public int CompareTo(Student
other) //以泛型方式声明,所以操作对象也就是 Student

{

if(this.Age > other.Age)

return 1;

if(this.Age
== other.Age)

return 0;

return
-1;  //大于 等于 小于 对应返回 1 / 0 / -1

}

}

这样操作 Student 类后,list.Sort() 功能也就可以通过调用 CompareTo
来对集合里的各个学生对象进行排序了。

C# 里的泛型如何使用?,布布扣,bubuko.com

时间: 2024-11-15 19:28:47

C# 里的泛型如何使用?的相关文章

F#新Bug,小心! module 里的泛型变量。

原则上,.Net不支持静态泛型变量,但是 F# 的语法支持,如: module Mithra = let Empty<'T> = Seq.empty <'T> 但是,这只是个语法糖而已.把这 F# 代码块编译成一个库,在C#里调用,即可看到,没有 Empty 变量,只有 Empty 函数.也就是说,这个“Empty”在 F# 里面,只是看起来像变量,实际上是在执行一个函数. 这有什么关系呢?答:有关系. 参照老赵的<逆泛型执行器>,如果有泛型变量的话.F# 下,实现逆泛

Swift语言里的泛型与异常处理

我感觉泛型挺难,希望对你们有帮助 //一个泛型a,b值交换的列子,可以传入什么类型 func mySwap<T>(inout a: T,inout b: T) { let temp = a a = b b = temp } var a = 111 var b = 222 mySwap(&a, b: &b) //普通整形a,b值交换列子,只能传入整形 func mySwap2(inout a: Int,inout b: Int) { let temp = a a = b b =

#读书笔记#Illustrated C# 2012第17章 Generics泛型(1)

什么是泛型(广泛意义上的"泛型")-->在特定语言(C#)里的泛型-->C#中的5个泛型类型 1.什么是泛型? 2.C#中提供了五种泛型(C#中的泛型) 3.C#中的泛型类(Generic Classes ) 4.泛型方法Generic Methods 5.泛型结构Generic Structs 6.泛型委托Generic Delegates 7.泛型接口Generic Interfaces ================= 1.什么是泛型 泛型是通过一种抽象的方式达到方

夯实JAVA基本之一 —— 泛型详解(1)

前言:无论何时,相信自己. 相关文章: 1.<夯实JAVA基本之一 -- 泛型详解(1)>2.<夯实JAVA基本之一 -- 泛型详解(2)> 一.引入 1.泛型是什么 首先告诉大家ArrayList就是泛型.那ArrayList能完成哪些想不到的功能呢?先看看下面这段代码: ArrayList<String> strList = new ArrayList<String>(); ArrayList<Integer> intList = new A

奇技淫巧:F#泛型特化的最终优化

上回讲到,F#中 module 里的泛型变量实际上是泛型函数.由此,在一个泛型特化的实现中出了岔子.最后通过泛型得以解决.使用 F# 来做泛型特化,相比 C# 有这个优势:F# 中直接支持函数赋值,而无须使用委托.避免了 C# 例子里面,为了节省 Lumbda 与委托之间的转换,而做出的丑陋的反射.拆箱操作.代码不再这么艰涩,我们重新来看看这段代码: module Mithra = type Cache<'T>() = static member val GetBytes: 'T->by

OOC,泛型,糟糕的设计。

虽然大部分都在谈ooc的编译器设计,但更多的内容在于程序设计的思想,复杂度,维护上面.我希望这篇文章能对读者有哪怕一丁点的帮助. 这篇文章遵循CC-BY-NC. = OOC,泛型,与那些糟糕的设计 原文地址:http://fasterthanlime.com/blog/2015/ooc-generics-and-flawed-designs 这篇文章同时发布在github上:https://github.com/zhaihj/ch_cn-ooc-generics-and-flawed-desig

java 反射和泛型

反射 在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问.检测和修改它本身状态或行为的一种能力.[1]用比喻来说,反射就是程序在运行的时候能够"观察"并且修改自己的行为. 要注意术语"反射"和"内省"(type introspection)的关系.内省(或称"自省")机制仅指程序在运行时对自身信息(称为元数据)的检测:反射机制不仅包括要能在运行时对程序自身信息进行检测,还要求程序能进一步根据这些信息改变程序

一句话,讲清楚java泛型的本质(非类型擦除)

背景 昨天,在逛论坛时遇到个这么个问题,上代码: public class GenericTest { //方法一 public static <T extends Comparable<T>> List<T> sort(List<T> list) { return Arrays.asList(list.toArray((T[]) new Comparable[list.size()])); } //方法二 public static <T exten

一文讲解Java泛型的本质(非类型擦除)

背景 昨天,在逛论坛时遇到个这么个问题,上代码: public class GenericTest { //方法一 public static <T extends Comparable<T>> List<T> sort(List<T> list) { return Arrays.asList(list.toArray((T[]) new Comparable[list.size()])); } //方法二 public static <T exten