(整理)C#基础知识_泛型的实现

    本文是截取自MSDN的文章部分,方便自己查看,原文地址:https://msdn.microsoft.com/zh-cn/library/ms379564(VS.80).aspx

    

    泛型实现

  表面上,C# 泛型的语法看起来与 C++ 模板类似,但是编译器实现和支持它们的方式存在重要差异。正如您将在后文中看到的那样,这对于泛型的使用方式具有重大意义。

  注 在本文中,当提到 C++ 时,指的是传统 C++,而不是带有托管扩展的 Microsoft C++。

  与 C++ 模板相比,C# 泛型可以提供增强的安全性,但是在功能方面也受到某种程度的限制。

  在一些 C++ 编译器中,在您通过特定类型使用模板类之前,编译器甚至不会编译模板代码。当您确实指定了类型时,编译器会以内联方式插入代码,并且将每个出现一般类型参数的地方替换为指定的类型。此外,每当您使用特定类型时,编译器都会插入特定于该类型的代码,而不管您是否已经在应用程序中的其他某个位置为模板类指定了该类型。C++ 链接器负责解决该问题,并且并不总是有效。这可能会导致代码膨胀,从而增加加载时间和内存足迹。

  在 .NET 2.0 中,泛型在 IL(中间语言)和 CLR 本身中具有本机支持。在编译一般 C# 服务器端代码时,编译器会将其编译为 IL,就像其他任何类型一样。但是,IL 只包含实际特定类型的参数或占位符。此外,一般服务器的元数据包含一般信息。

  客户端编译器使用该一般元数据来支持类型安全。当客户端提供特定类型而不是一般类型参数时,客户端的编译器将用指定的类型实参来替换服务器元数据中的一般类型参数。这会向客户端的编译器提供类型特定的服务器定义,就好像从未涉及到泛型一样。这样,客户端编译器就可以确保方法参数的正确性,实施类型安全检查,甚至执行类型特定的 IntelliSense。

  有趣的问题是,.NET 如何将服务器的一般 IL 编译为机器码。原来,所产生的实际机器码取决于指定的类型是值类型还是引用类型。如果客户端指定值类型,则 JIT 编译器将 IL 中的一般类型参数替换为特定的值类型,并且将其编译为本机代码。但是,JIT 编译器会跟踪它已经生成的类型特定的服务器代码。如果请求 JIT 编译器用它已经编译为机器码的值类型编译一般服务器,则它只是返回对该服务器代码的引用。因为 JIT 编译器在以后的所有场合中都将使用相同的值类型特定的服务器代码,所以不存在代码膨胀问题。

  如果客户端指定引用类型,则 JIT 编译器将服务器 IL 中的一般参数替换为 Object,并将其编译为本机代码。在以后的任何针对引用类型而不是一般类型参数的请求中,都将使用该代码。请注意,采用这种方式,JIT 编译器只会重新使用实际代码。实例仍然按照它们离开托管堆的大小分配空间,并且没有强制类型转换。

泛型的好处

  .NET 中的泛型使您可以重用代码以及在实现它时付出的努力。类型和内部数据可以在不导致代码膨胀的情况下更改,而不管您使用的是值类型还是引用类型。您可以一次性地开发、测试和部署代码,通过任何类型(包括将来的类型)来重用它,并且全部具有编译器支持和类型安全。因为一般代码不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。对于值类型,性能通常会提高 200%;对于引用类型,在访问该类型时,可以预期性能最多提高 100%(当然,整个应用程序的性能可能会提高,也可能不会提高)。本文随附的源代码包含一个微型基准应用程序,它在紧密循环中执行堆栈。该应用程序使您可以在基于 Object 的堆栈和一般堆栈上试验值类型和引用类型,以及更改循环迭代的次数以查看泛型对性能产生的影响。

时间: 2024-10-22 06:54:09

(整理)C#基础知识_泛型的实现的相关文章

SEO基础知识_绝密教程

<p align="center"> </p> <p>   </p> <p align="center"> 第一次接触SEO,请阅读本基础指南入门,也可以注册论坛:<a  1-1.html" target="_blank"><span style="color:black;">从一句话入门</span><span s

C#基础加强_泛型的基本原理

小弟初写博文,深感“易敲千行码,难下百余文”的道理. 内容粗略浅薄,望各位大神海涵! 动态数组ArrayList可以实现不断的增长,让我们感受到了在某些地方较数组有优越感.但它包含的数组类型是object类,意味着需要转为数组时,存在拆装箱操作,这带来不必要的麻烦,也损失了性能.而List<T>泛型集合的出现便大大解决了上述问题. //泛型 --泛指某一个类型.这种类型需要用户自己确定 List<string> lists = new List<string>(); /

黑马程序员——集合基础知识(泛型)

集合:泛型基础知识 泛型.(泛型就是类型参数化,默认的时object,虽然不用强制类型转换,这个就要你自己去写特性方法,比如compareto是string的特有方法吧,你可以写但是父类肯定调用不了) itnex t对象都是obj要使用对象的特性功能必须强.编译的时候没问题,因为都不知道你会传什么对象,你橙子也可以当作apple来传,设计的时候并不知道! 泛型作用.1.用于解决安全问题.运行时期出现的问题classcastexception转移到编译时期.2.迭代器里面的itnext()不用强转

Java基础知识_毕向东_Java基础视频教程笔记(22-25 GUI 网络编程 正则)

22天-01-GUIGUI:Graphical User Interface 图形用户接口 Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中CLI:Common line User Interface 命令行用户接口 Awt:Abstract Window ToolKit(抽象工具包),需要调用本地系统方法实现功能,属于重量级控件.Swing:在Awt的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现,增强了移植性,属于轻量级控件. 继

数据库基础知识_

01. 前言介绍 前言知识介绍说明 基础知识配置

计算机基础知识_硬件知识

硬件知识 计算机之父(冯·诺依曼)提出了一种结构电子管-晶体管-集成电路-大规模集成电路主要的要点是:1.)计算机存储是按照二进制存储的 作用是 可靠,稳定2.)计算机按照程序顺序执行 有五个要点1.)有标准的输入设备2.)有存储的戒指3.)能够进行算数运算和逻辑运算(cpu)4.)有控制5.)有标准的输出设备 常用的算法用处 1.冒泡排序 一般用于磁带(磁带,大规模存储的介质,没有随机内存的访问)所以冒泡排序是两两交换,可以用于这种设备.2.选择排序用于CD....等等可以有随机内存访问的介质

C#基础知识之泛型

泛型在c#中有很重要的位置,对于写出高可读性,高性能的代码有着关键的作用. 其实官方文档说明的很详细,我这边算是做个记录吧 一.什么是泛型? 泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个非常重要的新功能. 泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候.换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法.您可以通过数据类型的替代参数编写类或方法的规范.当编译器遇到类的构造函数或方法的函数调用时,它会生

计算机基础知识_原码反码补码

一.原码,反码,补码 1.原码 比如一个二进制数字 最高位是0,(0代表正数) 0010 1000 那么原码就是0010 1000 反码: 0010 1000 补码: 0010 1000 都是一样的,这个二进制数字的10进制是40 所以是正数 正数的原反补都是一样的 2.反码 反码就是原码的取反,二进制的 0变为1 1变为0 ,看最高符号位是0 还是1,如果是1,则你要0变为1,1变为0, 3.补码: 负数的的是原码 取反 在加1 变成补码(二进制数) 正数的原码 加上负数的补码就等于是做减法运

JAVA基础知识_对象

对象可以作为参数传递给方法 传递对象不是将对象本身的值传递给形参,而是将对象的引用值传递给形参 void method1(Num num){ num.i+=10; } method1方法体内形参内容的任何改动,也是对对象本身的改动 void method2(Num num){ num=new Num(); num.i=100; } 这里的对象内容并没有改变 因为Java中对象作为参数传递时,相当于是把对象在内存中的地址拷贝了一份传给参数 method1中,因为形参和对象有相同的内存地址,所以对形