为何引入泛型

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

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
  • 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
  • 可以对泛型类进行约束以访问特定数据类型的方法。
  • 在泛型数据类型中所用类型的信息可在运行时通过使用反射来获取。

下章概括:

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

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

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

C#高级编程之泛型一(泛型的引入、泛型的使用、何为泛型)的更多相关文章

  1. C#高级编程:泛型优点和特性

    泛型是CLR 2.0的一个新特性,在CLR 1.0中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就得以Object类为基础.而Object在编译期间没有类型安全性,因此必须进行 ...

  2. 《C#高级编程》之泛型--1创建泛型类

    .NET自从2.0版本开始就支持泛型. 非泛型链表 闲话休提,马上来看下非泛型的简化链表类,它可以包含任意类型的对象. LinkedListNode.cs中: 在链表中,一个元素引用另一个元素,所以必 ...

  3. C#高级编程9-第5章 泛型

    泛型 1.泛型概述 泛型是C#的部分与中间语言IL集成.创建的类或方法指定了类型,在实例化和调用时必须指定类型进行操作. 泛型可以用于类.方法.接口和委托以及结构. 泛型也是结构,同时是运行库CLR定 ...

  4. 《C#高级编程》读书笔记

    <C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) sh ...

  5. Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结

    Atitit.  高级软件工程师and 普通的区别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握常用的概念(ORM,IOC,AOP,event driv ...

  6. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  7. C#高级编程9-目录

    C#高级编程 ===================================================== .NET体系结构 核心C# 对象与类型 继承 泛型 数组 运算符和类型强制转换 ...

  8. Atitit. 高级软件project师and 普通的差别 高级编程的门槛总结

    Atitit.  高级软件project师and 普通的差别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握经常使用的概念(ORM,IOC.AOP,eve ...

  9. 2018.6.19 Java核心API与高级编程实践复习总结

    Java 核心编程API与高级编程实践 第一章 异常 1.1 异常概述 在程序运行中,经常会出现一些意外情况,这些意外会导致程序出错或者崩溃而影响程序的正常执行,在java语言中,将这些程序意外称为异 ...

  10. C#高级编程笔记 (6至10章节)运算符/委托/字符/正则/集合

    数学的复习,4^-2即是1/4/4的意思, 4^2是1*2*2的意思,而10^-2为0.01! 7.2运算符 符号 说明 例   ++ 操作数加1 int i=3; j=i++; 运算后i的值为4,j ...

随机推荐

  1. php-fpm 高并发 参数调整 转

    工作中经常会遇到会给客户配置服务器,其中有的客户还会有并发量要求,其中也会必须要用负载均衡承载压力的.增加服务器数量肯定能有效的提升服务器承载能力,但只有根据目前已有配置设置好单台服务器才能更好的发挥 ...

  2. ansible使用file模块管理受控机的目录与文件(ansible2.9.5)

    一,ansible的file模块的用途 file 模块实现对文件的基本操作. 例如: 创建文件或目录 删除文件或目录 修改文件权限等 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https:// ...

  3. 用Hugo在gitee上构建博客(Windows环境下)

    目录 用Hugo在gitee上构建博客(Windows环境下) 1.为什么要用gitee? 2.安装git 3.安装Hugo 4.创建远程仓库 5.搭建博客 (以下所有命令都在git bash中输入) ...

  4. vue3.0 的 Composition API 的一种使用方法

    网上讨论的文章已经很多了,这里举一个简单的例子来讨论一下 Composition API 的用法,具体问题才好具体讨论嘛. 假如我们要做一个论坛的讨论列表和分页,以前是把需要的数据都放在data里面, ...

  5. B. Petya and Divisors 解析(思維)

    Codeforce 111 B. Petya and Divisors 解析(思維) 今天我們來看看CF111B 題目連結 題目 略,請看原題 前言 看了別人的解答就豁然開朗 @copyright p ...

  6. SpringMVC中ModelAndView的两个jar包引起的思考servlet和portlet

    在使用ModelAndView时,需要去导包,但是有两个包. 检查前台form表单提交的也正确,后台这也没有问题. 后来发现竟然时导包导错误了. 到此,如果是因为到错包问题,应该就解决了. 但是,深入 ...

  7. js的几个牛逼操作

    1.条件语句的优化 // 根据颜色找出对应的水果 // bad function test(color) { switch (color) { case 'red': return ['apple', ...

  8. Netty源码解析 -- 事件循环机制实现原理

    本文主要分享Netty中事件循环机制的实现. 源码分析基于Netty 4.1 EventLoop 前面分享服务端和客户端启动过程的文章中说过,Netty通过事件循环机制(EventLoop)处理IO事 ...

  9. python机器学习TensorFlow框架

    TensorFlow框架 关注公众号"轻松学编程"了解更多. 一.简介 ​ TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运 ...

  10. [Luogu P3469] [POI2008]BLO-Blockade (割点)

    题面 传送门:https://www.luogu.org/problemnew/show/P3469 Solution 先跟我大声念: poi! 然后开始干正事. 首先,我们先把题目中的点分为两类:去 ...