C#高级编程之泛型一(泛型的引入、泛型的使用、何为泛型)

为何引入泛型

当我们要对不同类型的参数执行类似的方法时:如下所示功能打印传入参数的相关信息。

class CommonMethdod
    {
        /// <summary>
        /// show int
        /// </summary>
        public static void ShowParam(int iParam)
        {
            Console.WriteLine($"this is {typeof(CommonMethdod)},type={iParam.GetType().Name},param={iParam}");
        }
        public static void ShowParam(string sParam)
        {
            Console.WriteLine($"this is {typeof(CommonMethdod)},type={sParam.GetType().Name},param={sParam}");
        }    }

只是参数的不同,函数体以及函数名称都相同,很快我们想到了一种替代方案:将函数形参改为Object。

public static void ShowParam(object oParam)//函数声明oParam为object,但是实参为其子类-->LSP。
        {
            Console.WriteLine($"this is {typeof(CommonMethdod)},type={oParam.GetType().Name},param={oParam}");
        }

这似乎能解决我们的问题,一个方法可以适用于所有类型。之所以能解决的原因是:

Object是所有类的基类; 任何父类出现的地方(Object作为函数签名的形参),都可以用子类代替[实际传入实参](里氏替换原则LSP)。
但是其会存在这样的问题:

  1. 性能问题:会出现装箱与拆箱 。此处为 int->object(装箱),object->int实际类型(拆箱);

对于装箱拆箱的问题,这里就要了解C#装箱与拆箱的内部操作和C#内存模型。

详情请移步至:

https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/types/boxing-and-unboxing

https://blog.csdn.net/qiaoquan3/article/details/51439726

2.类型安全问题(泛型约束可解决)。如下所示:

程序编译通过,但是运行期间会抛异常,对于这种以Object作为基类来进行装箱拆箱的操作存在类型安全隐患。那在C#2.0泛型提出来后就很好的解决了这两个问题。

关于泛型约束的问题,明天再写。。。。

那泛型到底怎么使用呢?

泛型的使用:

如下所示为泛型方法的使用:

/// <summary>
        /// 泛型方法代替上一个Object方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tParam"></param>
        public static void ShowParam<T>(T tParam)
        {
            Console.WriteLine($"this is {typeof(T)},type={tParam.GetType().Name},param={tParam}");
        }

我们在客户端调用,代码如下:

class Program
    {
        static void Main(string[] args)
        {            Console.WriteLine("***********************Common********************");
            CommonMethdod.ShowParam(1);
            CommonMethdod.ShowParam("abc");
            Console.WriteLine("***********************Object********************");
            object obj = 3.1415926;
            CommonMethdod.ShowParam(obj);
            Console.WriteLine("***********************Generic********************");
            string str = "efg";
            int intVal = 0;
            CommonMethdod.ShowParam<string>(str);
            CommonMethdod.ShowParam<int>(intVal);
            Console.ReadKey();
        }
    }

结果如下:

泛型的定义

泛型将类型参数的概念引入 .NET,这样就可设计具有以下特征的类和方法:在客户端代码声明并初始化这些类或方法之前,这些类或方法会延迟指定一个或多个类型。其兼具可重用性、类型安全性和效率,这是非泛型类和非泛型方法无法实现的。

总结:

  • 使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能。
  • 泛型最常见的用途是创建集合类。
  • .NET 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。 应尽可能使用这些类来代替某些类,如 System.Collections 命名空间中的 ArrayList
  • 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
  • 可以对泛型类进行约束以访问特定数据类型的方法。
  • 在泛型数据类型中所用类型的信息可在运行时通过使用反射来获取。

下章概括:

如何对泛型类以及泛型方法进行约束以范文特定数据类型。

如何创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。

如何通过反射获取泛型数据类型进行相关操作。

(0)

相关推荐

  • C#反射

    C#反射

  • UNIX环境高级编程.pdf

    文档介绍:第1章U N I X基础知识1.1 引言所有操作系统都向它们运行的程序提供服务.典型的服务有执行新程序.打开文件.读文件.分配存储区.获得当前时间等等,本书集中阐述了U N I X操作系统各 ...

  • ARM架构芯片高级编程进阶手册

    ARM架构芯片高级编程进阶手册

  • #Javascript高级编程读书笔记#13.5 内存和性能

    13.5 内存和性能 Javascript 中函数都是对象,过多被添加到事件的处理程序都会占用内存,内存中对象越多性能就越差.其次,事先指定好所有事件处理程序而导致的DOM访问次数也会延迟整个页面的交 ...

  • 《C++ Primer》笔记 第10章 泛型算法

    迭代器令算法不依赖于容器,但算法依赖于元素类型的操作. 算法永远不会执行容器的操作.算法永远不会改变底层容器的大小. accumulate定义在头文件numeric中,接受三个参数,前两个指出需要求和 ...

  • Java基础之:泛型

    Java基础之:泛型 在不使用泛型的情况下,在ArrayList 中,添加3个Dog. Dog对象含有name 和 age, 并输出name 和 age (要求使用getXxx()). package ...

  • 我在UCL读建筑03 | 巴院高级参数化专业:建筑计算(AC),编程和数据的天堂

    "Still from 3D Game of Life" Mohamed Dawod, 2016 名校专业解读是LAC STUDIO推出的全新栏目,在这个栏目中我们将会邀请毕业于海 ...

  • 如何使用 Java 泛型来避免 ClassCastException

    泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 一句话解释什么是泛型? 泛型是相关语言特性的集合,它允许类或方法对各种类型的对象进行操作,同时提供编译时类型安全性检查 ...

  • Java泛型——泛型矩阵类

    Java泛型--泛型矩阵类 所有矩阵,加法和乘法操作都是类似,所以设计一个父类,不用管元素类型,目的描述所有类型的矩阵共享的通用操作 创建若干适用于指定矩阵类型的子类,实例:两种类型int和Ratio ...

  • Java泛型

    泛型的定义以及存在意义 泛型,即"参数化类型".就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具 ...