最近园里的TeamOne写了一篇《[C#] int与System.Int32有什么区别》,发现里面有不少精彩的评论,所以忍不住想这篇文章总结一下:>

本文的主要参考资料:

1.《理解C#中的System.Int32和int:并非鸡和鸡蛋》@Author:Dixin

2.《[C#] int与System.Int32有什么区别》@Author:TeamOne

一.问题的来源

MSDN说,int只不过是System.Int32的别名而已,也就是说:

int i=1;
System.Int32 i=1;

应该是等价的,或者说毫无区别的。

但在Dixin在用Reflector对.Net Framework的mscorlib.dll进行反汇编时,发现事情好像并不是这样,看下图:

上图是Dixin通过Reflector对mscorlib.dll进行反汇编后看到的System.Int32的定义,在上图中,我们看到Int32的定义中用到了int,如果按MSDN中说,int只是System.Int32的别名,那问题就来了:

(1).使用int和使用System.Int32是没有区别的。

(2).在C#的Struct定义中,字段中存在类型为自己的变量,是不允许的,例子如下:

public struct Test
{
public Test value;
}

上面这个例子编译会失败。由于System.Int32等价于int ,所以System.Int32的编译也应该会失败的!但事实上是,Reflector反编译出来的代码的确显示System.Int32定义中使用了int。这就不禁让人怀疑,int和System.Int32的关系到底是不是如MSDN所说的这么简单呢??究竟int是System.Int32的别名呢?还是System.Int32对int进行了封装呢?

二.int和System.Int32的关系

下图是我从微软官方介绍里截取的,我们先简单看一下.Net Framework的架构:

.Net Framework是一个基础平台,它要支持建立在此基础上的各种语言,以及跨语言程序之间的通信。如图:

由于上述原因,.Net Framework对外提供的资源必须是通用的,并且避免使用某种语言的特有称呼,以免造成不必要的混淆。

于是,这就有了int和System.Int32,它们的关系如下图:

System.Int32是.Net Framework对32位整数的标识,MSDN对这种类型标示的称呼是User Type。而int则是c#语言里面的特有称呼(这里它对应的.Net Framework里的System.Int32),MSDN对c#的int的称呼是Keyword。int就是System.Int32的别名而已!

那为什么我们在用Reflector反编译mscorlib.dll的时候,会得出第一幅图那种结果呢?

是这样的,在.Net Framework运行库里,有一种最基础的数据类型,叫“基元类型(primitive)”。这种数据类型是只提供给.Net Framework内部使用,外面是看不见的。其实在真正微软的System.Int32的源码中,用到的应该是int32。但是由于int32不是c#提供的类型,所以Reflector会自动把int32逆向为c#的int,这也就是为什么我们会在System.Int32定义中看到int的存在了。

这里我引用Dixin文章里的一段IL代码证明int32的存在:>

C#代码:

public int TestMethod(int value)
{
return value * 2;
}

对应得IL代码:

.method public hidebysig instance int32 TestMethod(int32 'value') cil managed
{
.maxstack 2
.locals init (
[0] int32 CS$1$0000)
L_0000: nop
L_0001: ldarg.1
L_0002: ldc.i4.2
L_0003: mul
L_0004: stloc.0
L_0005: br.s L_0007
L_0007: ldloc.0
L_0008: ret
}

想了解更多的关于“基元类型”的资料,可以参考这篇文章《认识基元类型、FCL类型及与CLR的相容情况》。

三.System.Int32在64位机器上

System.Int32在64位机器上还是表示32位的整数,也就是说C#的int在64位机器上也还是表示32位的整数。至于为什么,看下图:

如果System.Int32在64位机器为64bit,那么,这将会使在32位机器上的C#程序难以和64位上的C#程序沟通,试想一下,要把64bit的数据塞进32bit的空间中是一件多恶心的事情啊!所以,System.Int32在64位机器还是表示32位的长度,是很合理的。

《[C#] int与System.Int32有什么区别》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 跨域(Cross-Domain) AJAX for IE8 and IE9

    1.有过这样一段代码,是ajax $.ajax({ url: "http://127.0.0.1:9001", type: "POST", data: JSON ...

  2. 旧贴-在 win7 / win8 下安装苹果系统 (懒人版)

    前言 该文转载自远景论坛,发布时间2012年,仅供学习参考 这篇安装教程的素材在国庆就准备好了,但那时学习任务比较重,没有时间发帖,一直拖到现在.趁这个周末有空,赶紧写完它,希望能帮助一些景友. 论坛 ...

  3. Mybatis联合查询记录,左连接参数操作

    公司业务需求要做个列表的排序 而实际排序的字段不再本库中,需要跨库去拿到字段,因为是微服务体系架构,不可能Left join跨库的表,所以决定调用一次跨服务的API拿到排序相关的对象,里面包含需要排序 ...

  4. 基于R语言的结构方程:lavaan简明教程 [中文翻译版]

    lavaan简明教程 [中文翻译版] 译者注:此文档原作者为比利时Ghent大学的Yves Rosseel博士,lavaan亦为其开发,完全开源.免费.我在学习的时候顺手翻译了一下,向Yves的开源精 ...

  5. Java基础——类加载机制

    什么叫类加载 JVM把 .class 字节码文件加载到内存,并进行相关的校验.解析.初始化,最终转换为虚拟机可用的JAVA类型的过程,称为JVM类加载机制. (当然,JVM并不关心class文件的来源 ...

  6. zookeeper入门实例

    package org.merit.test.zookeepertest; import java.io.IOException;import java.util.List;import java.u ...

  7. PostgreSQL的 PITR实战---运用 recovery_target_time

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL基础知识与基本操作索引页     回到顶级页面:PostgreSQL索引页 看了很多的例子,没有发现具体讲 recove ...

  8. 【BZOJ1046】[HAOI2007]上升序列

    [BZOJ1046][HAOI2007]上升序列 题面 bzoj 洛谷 题解 \(dp\)完之后随便搞一下即可,注意不要看错题 代码 #include <iostream> #includ ...

  9. 关于Mybatis的Example(and ,or )应用

    近期的一个项目中遇到Mybatis的Example的and or 的应用,感觉有必要记录一下(个人见解,有问题请指出.谢谢) 1.在Example中的每一个Criteria相当于一个括号,把里面的内容 ...

  10. 全面解析C#中的异步编程

    当我们处理一些长线的调用时,经常会导致界面停止响应或者IIS线程占用过多等问题,这个时候我们需要更多的是用异步编程来修正这些问题,但是通常都是说起来容易做起来难,诚然异步编程相对于同步编程来说,它是一 ...