C#中的泛型

一、泛型的概念

定义:泛型允许我们延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。(也就是说泛型是可以与任何数据类型一起工作的类或方法)模块内高内聚,模块间低耦合。

泛型的使用:当我们的类/方法不需要关注调用者传递的实体是什么(公共基类工具类),这个时候就可以使用泛型。

注意:

集合中的项允许是 object 型的值,因此可以存放任意类型的值,无法确保存入集合中的值都是同一类型,而导致在处理时发生异常。

二、可空类型

       对于引用类型的变量来说,如果未对其赋值,在默认情况下是 Null 值,对于值类型的变量,如果未赋值,整型变量的默认值为 0

       但通过 0 判断该变量是否赋值了是不太准确的。在 C# 语言中提供了一种泛型类型(即可空类型 (System.Nullable))来解决值类型的变量在未赋值的情况下允许为 Null的情况。

可空类型的定义:

 System.Nullable<T> 变量名; 

 类型? 变量名; 

可空类型常用方法:

属性或方法

作用

HasValue

若变量有值则为True,若为null则为False

Value

返回可空类型变量中存储的真正的值,当HasValue为True时才可以使用

举例如下:

 class Program 

 { 

  static void Main(string[] args) 

  { 

  int? i = null; 

  double? d = 3.14; 

  if (i.HasValue) 

  { 

  Console.WriteLine("i 的值为{0}", i); 

  } 

  else 

  { 

  Console.WriteLine("i 的值为空!"); 

  } 

  if (d.HasValue) 

  { 

  Console.WriteLine("d 的值为{0}", d); 

  } 

  else 

  { 

  Console.WriteLine("d 的值为空!"); 

  } 

  }

 } 

三、泛型方法

C# 语言中泛型方法是指通过泛型来约束方法中的参数类型,也可以理解为对数据类型设置了参数。

如果没有泛型,每次方法中的参数类型都是固定的,不能随意更改。

在使用泛型后,方法中的数据类型则有指定的泛型来约束,即可以根据提供的泛型来传递不同类型的参数。

泛型方法的定义:

定义泛型方法需要在方法名和参数列表之间加上<>,并在其中使用 T 来代表参数类型。

注意:

C#中泛型方法中只能使用object类具有的方法。

举例如下:

 class Program 

 { 

  static void Main(string[] args) 

  { 

  //T设置为double类型 

  GenericFunc<double>(3.3, 4); 

  //T设置为int类型 

  GenericFunc<int>(3, 4); 

  } 

  //泛型方法 

  private static void GenericFunc<T>(T a, T b) 

  { 

  Console.WriteLine("参数1{0} 类型:{1},参数2{2},类型: {3}",a,a.GetType(),b,b.GetType()); 

  } 

 } 

四、泛型类

C# 语言中泛型类的定义与泛型方法类似,是在泛型类的名称后面加上,当然,也可以定义多个类型,即・・・>”

定义形式如下:

 class 类名<T1,T2,> 

 { 

  //类的成员 

 } 

这样,在类的成员中即可使用 T1T2 等类型来定义。

举例如下:

 ///  

 /// 自定义泛型类 

 ///  

 ///  

 class MyTest<T> 

 { 

  private T[] items = new T[3]; 

  private int index = 0; 

  //向数组中添加项 

  public void Add(T t) 

  { 

  if (index < 3) 

  { 

  items[index] = t; 

  index++; 

  } 

  else 

  { 

  Console.WriteLine("数组已满!"); 

  } 

  } 

  //读取数组中的全部项 

  public void Show() 

  { 

  foreach(T t in items) 

  { 

  Console.WriteLine(t);28 } 

  } 

 } 

五、泛型中的数据约束

泛型中的数据约束可以指定泛型类型的范围。

若给T类型的数据约束struct,则T只能接受struct的子类类型,否则编译错误。

六、泛型集合

C# 语言中泛型集合是泛型中最常见的应用,主要用于约束集合中存放的元素。

由于在集合中能存放任意类型的值,在取值时经常会遇到数据类型转换异常的情况,因此推荐在定义集合时使用泛型集合。

泛型集合中主要使用 List Dictionary

1List

List类是 ArrayList 类的泛型等效类。该类使用大小可按需动态增加的数组实现IList 泛型接口。

2Dictionary

Dictionary HashTable相对应的泛型集合,其存储数据的方式与哈希表相似,通过键/值来保存元素,并具有泛型的全部特征,编译时检查类型约束,读取时无须类型转换。

使用约束:

1、从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成

2、任何键都必须是唯一的

3、键不能为空引用null,若值为引用类型,则可以为空值

4KeyValue可以是任何类型(stringintclass 等)

七、IComparableIComparer自定义排序

C# 语言中提供了 IComparer IComparable 接口比较集合中的对象值,主要用于对集合中的元素排序。

IComparer 接口用于在一个单独的类中实现,用于比较任意两个对象。

IComparable 接口用于在要比较的对象的类中实现,可以比较任意两个对象。

在比较器中还提供了泛型接口的表示形式,即 IComparer IComparable 的形式。

1 IComparable 接口

要比较的自定义类型需要继承IComparable 接口,并实现以下方法:

方法

作用

CompareTo(T obj)

比较两个对象值,返回值小于0代表当前实例小于比较实例,返回值等于0代表二者相等。返回值大于0代表当前实例大于比较实例

如果需要对集合中的元素排序,通常使用 CompareTo 方法实现,下面通过实例来演示CompareTo 方法的使用。

  class Student:IComparable<Student> 

 { 

  //提供有参构造方法,为属性赋值 

  public Student(int id,string name,int age) 

  { 

  this.id = id; 

  this.name = name; 

  this.age = age; 

  }

  //学号 

  public int id { get; set; } 

  //姓名 

  public string name { get; set; } 

  //年龄 

  public int age { get; set; } 

  //重写ToString 方法 

  public override string ToString() 

  { 

  return id + "" + name + "" + age; 

  } 

  //定义比较方法,按照学生的年龄比较 

  public int CompareTo(Student other) 

  { 

  if (this.age < other.age) 

  { 

  return ‐1; 

  } 

  else if(this.age == other.age) 

  { 

  return 0; 

  } 

  else 

  { 

  return 1; 

  } 

  } 

 } 

2 IComparer 接口

如果要使得自定义类型可以使用泛型集合中的Sort方法进行排序,那么可自定义一个排序类,实现IComparer 接口中的以下方法:

方法

作用

Compare(T obj1,T obj2)

比较两个对象值,返回值小于0代表当前实例小于比较实例,返回值等于0代表二者相等。返回值大于0代表当前实例大于比较实例

新建学生类型排序类StudentComparer ,实现IComparer接口。

代码如下:

 ///  

 /// 比较类,用于两个Student对象比较 

 ///  

 class StudentComparer : IComparer<Student> 

 { 

 ///  

 /// 比较方法 

 ///  

 /// 

 ///  

 ///  

  public int Compare(Student x, Student y) 

  { 

  if(x.age < y.age) 

  { 

  return 1; 

  } 

  else if(x.age > y.age) 

  { 

  return ‐1; 

  } 

  else 

  { 

  return 0; 

  } 

  } 

 } 
 class Program 

 { 

 static void Main(string[] args) 

 { 

 //创建一个泛型列表,列表中的元素类型为Student 

 List<Student> stuList = new List<Student>(); 

 //在元素中添加三个元素 

 stuList.Add(new Student(3, "张三", 20)); 

 stuList.Add(new Student(1, "李四", 15)); 

 stuList.Add(new Student(2, "王五", 18)); 

     

 //遍历并输出 

 foreach (var stu in stuList) 

 { 

 Console.WriteLine(stu); 

 } 

 ​

 Console.WriteLine("排序后:"); 

 //排序 

 stuList.Sort(new StudentComparer()); 

 ​

 //遍历并输出 

  foreach(var stu in stuList) 

 { 

  Console.WriteLine(stu); 

  } 

  } 

 }

你可能感兴趣的:(介绍,c#)