• 《[C#] int与System.Int32有什么区别》


    《[C#] int与System.Int32有什么区别》

    最近园里的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位的长度,是很合理的。

  • 相关阅读:
    Kubernetes学习之路(十)之资源清单定义
    Kubernetes学习之路(十一)之Pod状态和生命周期管理
    Kubernetes学习之路(七)之Coredns和Dashboard二进制部署
    Kubernetes学习之路(九)之kubernetes命令式快速创建应用
    Kubernetes学习之路(八)之Kubeadm部署集群
    Ceph学习之路(三)Ceph luminous版本部署
    Kubernetes学习之路(六)之创建K8S应用
    Redis学习之路(二)之Redis入门基础
    Redis学习之路(一)之缓存知识体系
    OpenStack入门篇(二十二)之实现阿里云VPC的SDN网络
  • 原文地址:https://www.cnblogs.com/grj001/p/12224584.html
Copyright © 2020-2023  润新知