浅析C#中的泛型


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

1.什么是泛型?

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

    /// <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;
        }

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

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

2.泛型类

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

  /// <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();
     
    }

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

 


 3.类型参数的约束

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

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

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

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

 3.一般用到的约束如下

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

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

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

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

  /// <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();
     

    }

 

  /// <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();
     
    }

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

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

4.泛型方法

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

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

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

5.升华

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

C#多线程编程实例 线程与窗体交互【附源码】

C#数学运算表达式解释器

在C语言中解析JSON配置文件

C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码

本文永久更新链接地址:

相关内容