C# 运行时中的泛型
将泛型类型或方法编译为 Microsoft 中间语言 (MSIL) 时,它包含将其标识为具有类型参数的元数据。 泛型类型的 MSIL 的使用因所提供的类型参数是值类型还是引用类型而不同。
第一次用值类型作为参数来构造泛型类型时,运行时会创建专用泛型类型,将提供的参数代入到 MSIL 中的适当位置。 对于每个用作参数的唯一值类型,都会创建一次专用泛型类型。
例如,假设您的程序代码声明了一个由整数构造的堆栈:
Stack<int> stack;
在此位置,运行时生成 Stack<T> 类的专用版本,并相应地用整数替换其参数。 现在,只要程序代码使用整数堆栈,运行时就会重用生成的专用Stack<T> 类。 在下面的示例中,创建了整数堆栈的两个实例,它们共享 Stack<int> 代码的单个实例:
Stack<int> stackOne = new Stack<int>();
Stack<int> stackTwo = new Stack<int>();
但是,假定在代码中的另一个位置创建了使用不同值类型(比如 long 或用户定义的结构)作为其参数的另一个 Stack<T> 类。 因此,运行时将生成另一个版本的泛型类型,并在 MSIL 中的适当位置替换 long。 由于每个专用泛型类本身就包含值类型,因此不再需要转换。
对于引用类型,泛型的工作方式略有不同。 第一次使用任何引用类型构造泛型类型时,运行时会创建专用泛型类型,用对象引用替换 MSIL 中的参数。 然后,每次使用引用类型作为参数来实例化构造类型时,无论引用类型的具体类型是什么,运行时都会重用以前创建的泛型类型的专用版本。 之所以可以这样,是因为所有引用的大小相同。
例如,假设您有两个引用类型:一个 Customer 类和一个 Order 类,并且同时假设您创建了一个 Customer 类型的堆栈:
class Customer { }
class Order { }
Stack<Customer> customers;
此时,运行时将生成 Stack<T> 类的一个专用版本,该版本存储稍后将填写的对象引用,而不是存储数据。 假设下一行代码创建另一个引用类型的堆栈,该堆栈名为 Order:
Stack<Order> orders = new Stack<Order>();
不同于值类型,对于 Order 类型不创建 Stack<T> 类的另一个专用版本。 而是创建 Stack<T> 类的一个专用版本实例,并将 orders 变量设置为引用它。 假设接下来您遇到一行创建 Customer 类型堆栈的代码:
customers = new Stack<Customer>();
与前面使用 Order 类型创建的 Stack<T> 类一样,创建了专用 Stack<T> 类的另一个实例。 包含在其中的指针设置为引用 Customer 类型大小的内存区域。 因为引用类型的数量会随程序的不同而大幅变化,C# 泛型实现将编译器为引用类型的泛型类创建的专用类的数量减小到一个,从而大幅减小代码量。
此外,使用值类型或引用类型参数实例化泛型 C# 类时,反射可以在运行时查询它,并且可以确定它的实际类型及其类型参数。
C# 运行时中的泛型的更多相关文章
- 【转】Sqlite 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该...
开发环境: vs2010+.net framework 4.0+ System.Data.SQLite.DLL (2.0)今天在做Sqlite数据库测试,一运行程序在一处方法调用时报出了一个异常 混合 ...
- Oracle开始从Java运行时中移除JAR包
早在2012年8月,在Java平台首席架构师Mark Reinhold宣布模块化项目Jigsaw之后不久,JEP 162这一题为“准备模块化”的提案就指出,在Jigsaw项目中为模块化系统开发的代码不 ...
- SQLite.dll混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
其他信息: V5.7.4.4 Can't find the System.Data.SQLite.dll more info : 混合模式程序集是针对"v2.0.50727"版的运 ...
- <VS2010>混合模式程序集是针对“v2.0”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集
在把以前写的代码生成工具从原来的.NET3.5升级到.NET4.0时,将程序集都更新后,一运行程序在一处方法调用时报出了一个异常: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有 ...
- Erlang运行时中的无锁队列及其在异步线程中的应用
本文首先介绍 Erlang 运行时中需要使用无锁队列的场合,然后介绍无锁队列的基本原理及会遇到的问题,接下来介绍 Erlang 运行时中如何通过“线程进度”机制解决无锁队列的问题,并介绍 Erlang ...
- 使用 Windows 运行时中异步性来始终保持应用程序能够快速流畅地运行
转自:http://blogs.msdn.com/b/windowsappdev_cn/archive/2012/03/26/windows.aspx 人类的思维方式在本质上不是同步的,这直接影响着我 ...
- VS报错之混合模式程序集是针对“v1.1.4322”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
看到一个kinect大牛编写的一个水果忍者的体感游戏版本,让我为自己一直以来只用现有的网页游戏来模拟kinect体感游戏控制感到惭愧,没办法,我还是菜鸟.学习一段后自己模仿星际大战这个游戏,自己写了一 ...
- C#连接Sqlite 出现:混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。的解决方案
C#连接Sqlite 出现: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集.的解决方案 C#连接sqlite数据库代码 ...
- c# .netframwork 4.0 调用 2.0时报错 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
“System.IO.FileLoadException”类型的未经处理的异常在 XXX.dll 中发生 其他信息: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的 ...
随机推荐
- 面试问题Distilled
1. 你在项目里都用过哪些Spring的组件 2. Spring AOP的实现原理 3. Hibernate的乐观锁和悲观锁 4. Hibernate的缓存机制 5. 对SOA的了解和认识 6. 谈谈 ...
- luogu P1325 雷达安装
题目描述 描述: 假设海岸线是一条无限延伸的直线.它的一侧是陆地,另一侧是海洋.每一座小岛是在海面上的一个点.雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围d.你的任务是建立尽量少 ...
- HDU 1754 I Hate It<区间最值 单点修改>
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- [ARC100]E:Or Plus Max(FZT)
https://arc100.contest.atcoder.jp/tasks/arc100_c 一个很自然的想法是,对于每个K求出i or j=k的所有a[i]+a[j]的最大值ans[k],答案就 ...
- Java概述--Java开发实战经典
1)Java有三个发展方向,分别是Java SE,Java EE,Java ME.以下简要介绍. a.Java SE,Java Standard Edition(java标准版),包含了构成java语 ...
- Java高级架构师(一)第07节:远程使用以及冲突解决
- Radius报文解析(转)
RADIUS ,是远程认证拨号用户服务的简称.RADIUS原先设计的目的是为拨号用户进行认证和计费.后来经过多次改进,形成了一项通用的认证计费协议,主要完成在网络接入设备和认证服务器之间承载认证.授权 ...
- 触摸事件onTouchListener
1.效果图: (1)MainAcivity.java package com.example.app3; import android.content.DialogInterface; import ...
- 设置cookie和查找cookie的方法
1.设置cookie(名称,值,过期时间) function setCookie(key,value,d){ if(d === undefined){ document.cookie = encode ...
- WebLogic Server 12.2.1 多租户安装配置
1.安装WebLogic 12.2.1版本 下载安装的时候记住选择Fusion Middleware Infrastructer Installer. 2.安装OTD OTD需要单独下载安装,安装的时 ...