NET 泛型,详细介绍
今天的文章是因为再给一个朋友讲这个的时候随手记录下整理出来的。说白了就是把前辈们曾经给我吹过的我又吹了出去。
泛型:是C# FrameWork 2.0 时代 加入进来的,可以说对与Net开发人员来说泛型是无处不再的,喜欢看源码的同学,可能会有发现,包括MVC里面基本上也是有很多发泛型,还有很多设计模式也需要搭配泛型来实现,包括项目架构
泛型的存在,是代码利用率复用性都大大的提升了,有时候Object 也是可以起到相同的作用,为什么使用泛型 为什么不是用Obj ,我们来看一下:
下面我们列出两个最基础的方法:
/// <summary>
/// 返回int
/// </summary>
/// <param name="I"></param>
/// <returns></returns>
public int ShowInt(int I)
{
return I;
}
/// <summary>
/// 返回String
/// </summary>
/// <param name="I"></param>
/// <returns></returns>
public string ShowString (string I)
{
return I;
}
上面的两个方法自从参数 进来到参数出去的这一个过程中我们没有进行参数方面的转换,也就是说单纯的针对的参数类型上面我们程序代码是没有损失任何的性能的。一位没有存在拆箱装箱的过程。
我们在看两个方法:我们使用了在C# 1.0 时代就存在的一个类型 是Object
/// <summary>
/// 返回int
/// </summary>
/// <param name="I"></param>
/// <returns></returns>
public int ShowString(object I)
{
return Convert.ToInt32(I);
}
/// <summary>
/// 返回String
/// </summary>
/// <param name="I"></param>
/// <returns></returns>
public string ShowString(object I)
{
return I.ToString();
}
这里我们使用的阐述类型是Obj ,Object 是引用类型,也是所有类型的父类,可以包容所有的类型,但是就单说处理参数类型的时候我们需要去转换一下才能进行使用,在这个转换的过程中我们已经损失了性能,但是使用Obj 的时候我们可以和成一个方法减少代码量,提升了代码的复用率。
比如:
/// <summary>
/// 返回object
/// </summary>
/// <param name="I"></param>
/// <returns></returns>
public object ShowType(object I)
{
return I;
}
现在简写成为这样后,我们是一个公用的方法:虽然说内部不用去转换了但是,在调用后,还是需要类型的转换同样的需要损失性能。中间性能之所以会损失是因为Obj是引用类型,存放在堆上的,假如说我们传的参数是int或其他的值类型来使用我们的公共方法,就会进行一次包装的过程,把存放在栈里面的值类型移动包装成为引用类型存放到堆里面,使参数符合当前方法的类型,这个过成也就是装箱(需要重新分配内存),但是我们在使用的时候,又需要把他拿出来进行一下装换转换为值类型,这个过程又称为拆箱,
我们在来使用一个方法:使用 2.0时代出现的泛型:
/// <summary>
/// 返回 T
/// </summary>
/// <param name="Parameter"></param>
/// <returns></returns>
public T Show<s>(T Parameter)
{
return Parameter;
}
为什么会使用泛型 是因为泛型方法再调用的时候有延时声明的功能这里的延时声明式只参数,泛型里面的 T ,其实咱们也可以理解为 占位符具体为谁占位的,等到调用的时候才会知道。
如下:
int parameter = ;
//在调用的时候声明参数类型
parameter = new Common().Show<int>(parameter);
//如果调用的时候不去声明的话,JIT编译的时候野会帮我们自动计算
parameter = new Common().Show(parameter);
这个时候不会损耗什么性能。延时声明也是咱们在进行框架设计的时候常用的一种思想,提高框架的性能。泛型不只是可以声明泛型方法:
泛型类:
/// <summary>
/// CURD 操作类
/// </summary>
/// <typeparam name="T"></typeparam>
public class ConmonClass<T>
{
public void Add(T s) { };
public void Update(T s) { };
public void Del(T s) { };
public void Select(T s) { };
}
这样使用的话,在咱们真正的项目,我们可以把某些基础的操作用一个类去搞定,使用的时候调用就是了,减少代码的冗余,增加复用性,重用率。
泛型接口:
/// <summary>
/// CURD 操作接口类
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ConmonInterface<T>
{
T Add(T s);
T Update(T s);
T Del(T s);
T Select(T s);
}
泛型委托:
//泛型委托
public delegate T GetHandler<T>();
我想以上的操作在我们开发项目的时候会经常见到,或使用到
以上代码需要我们注意的时候,泛型类不能被继承,如果想要继承的话需要在继承的时候,给我们的不确定参数确定下参数类型。包括泛型接口也是一样的。
如下:
public class Son : ConmonClass<Common>
{};
/// <summary>
/// 实现泛型接口
/// </summary>
public class SonInterface : ConmonInterface<Common>
{
public Common Add(Common s)
{
throw new NotImplementedException();
} public Common Del(Common s)
{
throw new NotImplementedException();
} public Common Select(Common s)
{
throw new NotImplementedException();
} public Common Update(Common s)
{
throw new NotImplementedException();
}
}
如果说不指定泛型类型的参数类型式其实我们一样是可以继承的。需用继承者同样是泛型的。
建议:长期使用Net的同学我想我们需要加强一下泛型的认识了,因为在NetCore中常常会使用依赖注入,在使用泛型类的时候我们可能会多少有点麻烦的,泛型方法相对来说要简单的,如果说要想让我们的框架实现高度的内聚,大家需要多多理解。
泛型的约束,多重约束相当重要,代表我们是否能很好的利用泛型。
泛型的约束类型大概分为如下几种:
引用类型约束: |
表明泛型参数只能是引用类型的: |
值类型约束: |
表明泛型参数只能是值类型的: |
无参数构造函数约束: |
泛型是可以实例化的。 |
基类约束 |
必须满足基类中的某些属性 |
接口约束 |
必须满足接口中的某些属性 |
具体的就不代码了。
有不足之处 希望大家指出相互学习,
本文原创:转载请注明出处 谢谢!
NET 泛型,详细介绍的更多相关文章
- 问题:C# Dictionary嵌套使用;结果:嵌套Dictionary添加 , C#2.0泛型详细介绍
Dictionary<int, Dictionary<string, string>> dict1 = new Dictionary<int, Dictionary< ...
- Java Annotation认知(包括框架图、详细介绍、示例说明)
摘要 Java Annotation是JDK5.0引入的一种注释机制. 网上很多关于Java Annotation的文章,看得人眼花缭乱.Java Annotation本来很简单的,结果说的人没说清楚 ...
- Java Annotation认知(包括框架图、详细介绍、示例说明)(转)
本文转自:http://www.cnblogs.com/skywang12345/p/3344137.html 网上很多关于Java Annotation的文章,看得人眼花缭乱.Java Annota ...
- springboot 学习之路 18(webflux详细介绍(2))
webflux的详细介绍 引言:上一节已经简单介绍webflux的一些基本概念,本章继续学习webflux的原理和实战方面的东西: Spring WebFlux架构: note:注意理解上面这张图.下 ...
- [No0000A7]批处理经常用到的变量及批处理>NUL详细介绍
绝对路径是指调用绝对的程序位置的路径,例如: start C:\Windows\test.exe 相对路径是文件改变路径以后还会按照变量的路径所在位置去调用,例如: start %WINDIR%\te ...
- linux配置网卡IP地址命令详细介绍及一些常用网络配置命令
linux配置网卡IP地址命令详细介绍及一些常用网络配置命令2010-- 个评论 收藏 我要投稿 Linux命令行下配置IP地址不像图形界面下那么方 便,完全需要我们手动配置,下面就给大家介绍几种配置 ...
- _MSC_VER详细介绍
_MSC_VER详细介绍 转自:http://www.cnblogs.com/braver/articles/2064817.html _MSC_VER是微软的预编译控制. _MSC_VER可以分解为 ...
- php CGI、Fastcgi、PHP-FPM的详细介绍与之间的关系
以下PHP CGI.Fastcgi.PHP-FPM的一些信息归纳和汇总----->详细介绍与之间的关系 一:CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的 web ...
- RabbitMQ消息队列(一): Detailed Introduction 详细介绍
http://blog.csdn.net/anzhsoft/article/details/19563091 RabbitMQ消息队列(一): Detailed Introduction 详细介绍 ...
- doT.js详细介绍
doT.js详细介绍 doT.js特点是快,小,无依赖其他插件. 官网:http://olado.github.iodoT.js详细使用介绍 使用方法:{{= }} for interpolati ...
随机推荐
- 机器学习(2) - KNN识别MNIST
代码 https://github.com/s055523/MNISTTensorFlowSharp 数据的获得 数据可以由http://yann.lecun.com/exdb/mnist/下载.之后 ...
- ubuntu 16.04安装smatrgitHG工具
SmartGit/HG 是一款开放源代码的.跨平台的.支持 Git 和 Mercurial 的 SVN 图形客户端,可运行在Windows.Linux 和 MAC OS X 系统上. 1.安装 Ubu ...
- Activity的生命之路
activity的生命周期这张图是最经典的了,下面我就说一下 这张图的脉络: 第一条线我们这么走 onCreate→onStart→onResume→onPause→onStop→onDestroy ...
- SVN使用教程2017.10.6
http://www.cnblogs.com/mq0036/p/5250198.html
- 你不知道的JavaScript--Item2 浮点数精度
理解JavaScript的浮点数 大多数编程语言都有几种数值型数据类型,但是JavaScript却只有一种.你可以使用typeof 运算符查看数字的类型.不管是整数还是浮点数,JavaScript都将 ...
- 教小朋友学Linux
Linux最基础之<小朋友也能学会Linux>... 1.Linux 知识积累: Linux 英文解释为 Linux is not Unix.学习Linux必须要熟练使用的操作系统是Cen ...
- 简书markdown教程
1 支持 Markdown 的编辑器 Windows 推荐 Sublime Text 3,强大优雅的编辑器.MarkdownPad,一款可以直接预览排版效果的编辑器. Mac 推荐 Ulysess,专 ...
- pip 安装mysqlclient报错OSError: mysql_config not found
执行 pip install mysqlclient 报错信息如下: [root@CentOS7-demo bin]# pip install mysqlclient Collecting mysql ...
- python 3.6 lxml标准库lxml的安装及etree的使用注意
据我所知,python 3.5之后的lxml模块里面不再包含etree,那么要怎么解决这个问题呢? lxml模块下的etree函数的使用问题,部分lxml模块不再支持etree方法,因此只能想办法下载 ...
- IE下获取XPATH小工具,支持32/64位
背景是曾经友情支持了测试组一小段时间,发现他们使用selenium做页面的自动化测试,需要用到XPath,但IE下没有获取XPath的工具,只能在Firefox和chrome下获取,步骤还比较麻烦.而 ...