浅析C#中的泛型

来源:互联网 发布:富士施乐mac驱动 编辑:程序博客网 时间:2024/05/27 21:03

 

 接触泛型很长时间了,但总没有时间对起做个总结,不得不说泛型是个好东西,能大大的减少我们的代码量,下面来说一下有关泛型的相关知识。

 1.什么是泛型?

 在介绍泛型之前,先看一个小的事例。

<span style="font-size:18px;">     /// <summary>        /// 计算两个整形相加        /// </summary>        /// <param name="a"></param>        /// <param name="b"></param>        /// <returns></returns>        public int Add(int a, int b)        {            return a + b;        }        /// <summary>        /// 计算两个浮点型相加        /// </summary>        /// <param name="a"></param>        /// <param name="b"></param>        /// <returns></returns>        public decimal Add(decimal a, decimal b)        {            return a + b;        }</span>


 上述是两个非常简单的方法,实现了两个数的相加操作。但是如果细心的话,也会发现两个方法有相同的地方,我们可以写成一下的格式  public T Add(T a,T b),至于T是什么东东,不管他,反正就是一个占位符,就好比上述的Int 或者Decimal,所以如果有这样一个占位符,能够代替所有的类型不就好了吗?因此.net专门提供了专门的语法来替代占位符,其中一种就是在定义类型的时候传递,此时,类型也就变成了泛型类。


 小结:泛型允许我们声明类型参数化的代码,我们可以用不同的类型进行实例化。也就是说,我们可以用"类型占位符"来写代码,然后在创建类的实例时提供真实的类型。


 2.泛型类

 声明一个泛型类也特别的简单,跟平常的类书写大致相似,只不过把需要改变的地方用类型占位符替换即可。

<span style="font-size:18px;">  /// <summary>    /// 泛型类    /// </summary>    /// <typeparam name="T1">泛型参数</typeparam>    /// <typeparam name="T2">泛型参数</typeparam>    class SomeClass<T1,T2> where T1 :new() where T2:new()    {        //根据泛型参数,创建一个类        public T1 SomeVar = new T1();        public T2 OtherVar = new T2();          }</span>

看了上述代码是否感觉特别的清爽,就是这么简单,与普通类的区别就是在类名之后放置了一组尖括号,并且在尖括号中用逗号分隔占位符来表示希望提供的类型。而在泛型类声明的主体中使用类型参数来表示应该被替代的类型。


 3.类型参数的约束

 如果你在泛型类中,直接运用占位符来执行+ -操作的话,编译器会直接报错,因为此时编译器并不知道T的具体类型,尽管所有的类型都继承自System.Object,因为泛型类并不知道他们保存的是什么类型,不会知道这些类型实现的成员。

 看上述实例,就会发现为何在泛型类中多出了一个where字句,这就是用来约束占位符。

 1.每个占位符都有自己的where子句

 2.如果形参有多个约束,他们在where子句中使用逗号分隔

 3.一般用到的约束如下

      Class:任何引用类型,包括类、数组、委托和接口都可以用作实参

      Struct:任何值类型都可以被用作类型实参

      Interface:只有这个接口或者实现接口的类型才能用作实参

      New():任何带有无参构造函数的类型都可以用作实参,这叫做构造函数约束

<span style="font-size:18px;">  /// <summary>    /// 泛型类    /// </summary>    /// <typeparam name="T1">泛型参数</typeparam>    /// <typeparam name="T2">泛型参数</typeparam>    class SomeClass<T1,T2> where T1 :class,new() where T2:class,new()    {        //根据泛型参数,创建一个类        public T1 SomeVar = new T1();        public T2 OtherVar = new T2();          }</span>




<span style="font-size:18px;">  /// <summary>    /// 泛型类    /// </summary>    /// <typeparam name="T1">泛型参数</typeparam>    /// <typeparam name="T2">泛型参数</typeparam>    class SomeClass<T1,T2> where T1 :class,new() where T2:class,new()    {        //根据泛型参数,创建一个类        public T1 SomeVar = new T1();        public T2 OtherVar = new T2();          }</span>

 看上述代码,主要是注意一下泛型约束的格式规则

 注意:泛型约束也会涉及到一个次序的问题,存在构造函数的约束,new()必须放在最后


 4.泛型方法

  既然知道了泛型类,泛型方法也就明白多了,写法基本上是相同的。

<span style="font-size:18px;">  /// <summary>        /// 泛型方法        /// </summary>        /// <typeparam name="S">泛型参数</typeparam>        /// <typeparam name="T">泛型参数</typeparam>        /// <param name="p">参数</param>        public void PrintData<S, T>(S p) where S : class        {             ///代码体        }</span>

 

 上面就是一个泛型方法的实例,基本的操作与普通的方法相似。


 5.升华

  说了这么多,到底什么是泛型?作为泛型我只提供了服务,但是我不太知道具体的执行人是什么,也就是泛型占位符,但是只要你提供了执行者,也就是泛型参数,你就具有了相应的服务和功能。









 

 



0 0
原创粉丝点击