.NET的基元类型包括哪些?Unmanaged和Blittable类型又是什么?

这篇具有很好参考价值的文章主要介绍了.NET的基元类型包括哪些?Unmanaged和Blittable类型又是什么?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在讨论.NET的类型系统的时候,我们经常提到“基元类型(Primitive Type)”的概念,我发现很多人并没有真正理解基元类型就究竟包含哪些(比如很多人觉得字符串是基元类型)。除了明确界定基元类型外,本篇文章还会简单介绍额外两种关于类型的概念——Unmanaged类型和Blittable类型。

一、Primitive Type
二、Unmanaged Type
三、Blittable Type

一、Primitive Type

.NET下的基元类型(Primitive Type)如下14个。我们可以这样来记:长度(字节数)分别为1、2、4、8的有/无符号的整数;外加两个基于指针宽度(下x86=4; x64=8)的整数,计10个。长度(字节数)分别为4和8的单精度和双精度浮点数,计2个。外加布尔类型和字符类型, 计2个。所以我们熟悉的String(string)和Decimal(decimal)并不是基元类型。

  • 整数(10):Byte(byte)/SByte(sbyte), Int16(short)/UInt16(ushort), Int32(int)/UInt32(uint), Int64(long)/UInt64(ulong), IntPtr(nint)/UIntPtr(nuint)
  • 浮点(2):Float(float), Double(double)
  • 布尔(1):Boolean(bool)
  • 字符(1):Char(char)

对于某个指定的Type对象,我们可以利用它的IsPrimitive属性确定它是否为基元类型。

public abstract class Type
{
    public bool IsPrimitive { get; }
}

Type对象的IsPrimitive属性值最终来源于RuntimeTypeHandle类型如下这个内部静态方法IsPrimitive。从该方法的实现和CorElementType的枚举成员也可以看出,枚举值2-13,外加CorElementType.I(IntPtr)和CorElementType.U(UIntPtr)这14个类型属于基元类型的范畴,这与上面的列表是一致的。

public struct RuntimeTypeHandle
{
    [SecuritySafeCritical]
    internal static bool IsPrimitive(RuntimeType type)
    {
        CorElementType corElementType = GetCorElementType(type);
        if (((int)corElementType < 2 || (int)corElementType > 13) && corElementType != CorElementType.I)
        {
            return corElementType == CorElementType.U;
        }
        return true;
    }
}

[Serializable]
internal enum CorElementType : byte
{
    End = 0,
    Void = 1,
    Boolean = 2,
    Char = 3,
    I1 = 4,
    U1 = 5,
    I2 = 6,
    U2 = 7,
    I4 = 8,
    U4 = 9,
    I8 = 10,
    U8 = 11,
    R4 = 12,
    R8 = 13,
    String = 14,
    Ptr = 15,
    ByRef = 16,
    ValueType = 17,
    Class = 18,
    Var = 19,
    Array = 20,
    GenericInst = 21,
    TypedByRef = 22,
    I = 24,
    U = 25,
    FnPtr = 27,
    Object = 28,
    SzArray = 29,
    MVar = 30,
    CModReqd = 31,
    CModOpt = 32,
    Internal = 33,
    Max = 34,
    Modifier = 64,
    Sentinel = 65,
    Pinned = 69
}

二、Unmanaged Type

顾名思义,Unmanaged类型可以理解不涉及托管对象引用的值类型。如下的类型属于Unmanaged 类型的范畴:

  • 14种基元类型+Decimal(decimal)

  • 枚举类型

  • 指针类型(比如int*, long*)

  • 只包含Unmanaged类型字段的结构体

如果要求泛型类型是一个Unmananged类型,我们可以按照如下的方式使用unmanaged泛型约束。我在《如何计算一个实例占用多少内存?》提到过,只有Unmananged类型采用使用sizeof操作符计算大小。

public static unsafe int SizeOf<T>() where T : unmanaged
{
    return sizeof(T);
}

三、Blittable Type

Blittable是站在基于P/Invoke的互操作(InterOp)角度对传递的值是否需要进行转换(Marshaling)而作的分类。Blittable类型要求在托管内存和非托管内存具有完全一致的表示。如果某个参数为Blittable类型,在一个P/Invoke方法调用非托管方法的时候,该参数就无需要作任何的转换。与之类似,如果调用方法的返回值是Blittable类型,在回到托管世界后也无需转换。如下的类型属于Blittable类型范畴:

  • Boolean(bool)Char(char)之外的12种基元类型,因为布尔值True在不同的平台可能会表示成1或者-1,对应的字节数可能是1、2或者4,字符涉及不同的编码(Unicode和ANSI),所以这两种类型并非Blittable类型;
  • Blittable基元类型的一维数组;
  • 采用SequentialExplicitly布局的且只包含Blittable类型成员的结构或者类,因为采用这两种布局的对象最终会按照一种确定的格式转换成对应的C风格的结构体。如果采用Auto布局,CLR会按照少占用内存的原则对字段成员重新排序,意味着其内存结构是不确定的。

顺便强调一下,DateTime/DateTimeOffset都采用Auto布局(如下所示),Guid虽然是一个默认采用Sequential布局的结构体,但是最终映射在内存种的字节依赖于字节序(Endianness),所以具有这三种类型字段的结构体或者类都不是Blittable类型。

[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct DateTime
{ }

[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct DateTimeOffset
{ }

只有Blittable类型的实例才能调用GCHandle的静态方法Alloc为其创建一个Pinned类型的GC句柄。以如下的代码为例,类Foobar的两个属性都是Blittable类型,我们通过标注在类型上的StructLayoutAttribute将布局类型显式设置成Sequential使其称为了一个Blittable类型。

GCHandle.Alloc(new Foobar(), GCHandleType.Pinned);

[StructLayout(LayoutKind.Sequential)]
public class Foobar
{
    public int Foo { get; set; }
    public double Bar { get; set; }
}

如果Foobar类定义成如下的形式,都不能使其称为一个Blittable类型。前者默认采用Auto布局,后者的Bar属性并不是Blittable类型。如果将这样Foobar对象作为参数按照上面的方式调用GCHandle. Alloc方法,会直接抛出ArgumentException异常,并提示“Object contains non-primitive or non-blittable data. (Parameter 'value')”。文章来源地址https://www.toymoban.com/news/detail-479736.html

public class Foobar
{
    public int Foo { get; set; }
    public double Bar { get; set; }
}

[StructLayout(LayoutKind.Sequential)]
public class Foobar
{
    public int Foo { get; set; }
    public DateTime Bar { get; set; }
}

到了这里,关于.NET的基元类型包括哪些?Unmanaged和Blittable类型又是什么?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 什么是.NET?什么是.NET Core?以及什么是.NET Framework,.NET和.NET Core区别又是什么呢?

    概述 对于.NET平台的初学者来说,有时候比较困惑“什么是.NET?什么是.NET Core?.NET和.NET Core区别又是什么呢?”。确实,目前微软的开发平台有两种不同的.NET运行时环境,一种是.NET Framework,另一种则是.NET Core(.NET 5),不同的目标框架运行时环境不同。 那这两者的区别到底是

    2024年02月06日
    浏览(62)
  • 搜索引擎优化包括哪些内容(优化的内容包括)

    搜索引擎优化搜索引擎优化的重要好处之一是它可以提供独特的相关流量。依据搜索引擎优化营销推广,可以帮助这种积极寻找你所提供的物件的人更很容易找到你。这促进研究变为搜索引擎优化对策中的一个重要组成一部分,它呈现了指导思想顾客在寻找相关产品和

    2024年02月06日
    浏览(60)
  • 云安全包括哪些方面?

    随着云计算的快速发展,云安全问题也日益受到关注。云安全不仅涉及到个人数据安全,还涉及到国家安全、社会稳定等方面。因此,了解云安全包括哪些方面对于保护个人隐私和企业数据安全具有重要意义。本文将从多个角度探讨云安全所涉及的方面。 ​一、数据安全 数

    2024年01月23日
    浏览(42)
  • 网络安全主要包括哪些方面

    什么是网络安全?网络安全主要包括哪些方面? 什么是网络安全? 网络安全就是网络上的信息安全,是指网络系统中的硬件、软件和系统中的数据都能受到保护,不会因意外或恶意原因而损坏、更改或泄露。系统连续可靠地正常运行,网络服务不中断。   从广义上讲,所有涉及

    2024年02月11日
    浏览(46)
  • 软件开发技术包括哪些呢?

    软件开发技术包括多种编程语言、开发框架、工具和方法,以满足不同类型的应用和项目需求。以下是一些常见的软件开发技术: 1、编程语言:各种编程语言用于开发不同类型的软件,如Java、Python、C++、C#、JavaScript、Ruby、PHP、Swift、Kotlin等。 2、Web开发技术:用于创建网站

    2024年02月08日
    浏览(45)
  • 智能运维乱象有哪些?智能运维业务包括哪些

    nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;在实施智能运维过程中可能遇到的乱象及其原因,系统地阐述智能运维业务所涵盖的各个方面,包括但不限于预防性维护、故障检测与诊断、自动化修复以及持续的性能优化等关键组成部分。 实施智能运维过程中可能遇到的乱象及原因包括: 数

    2024年02月21日
    浏览(33)
  • 安全服务包括哪些内容,安服工程师需要哪些技能

    安全服务是一系列措施和程序,旨在保护组织和个人免受各种安全威胁。这些服务涵盖了从网络安全、数据保护、身份和访问管理,到应用程序安全、安全监控和响应、以及物理安全等多个方面。安全服务的目标是确保信息技术系统、数据以及物理环境的安全和完整性,同时

    2024年02月03日
    浏览(70)
  • 水库自动化监测系统包括哪些内容

    随着科技的不断进步,水库管理正逐步实现自动化和智能化。水库自动化监测系统是一种利用水位、流量、水温及气象等传感器组成的水情自动监测系统,其在水库大坝安全监测领域发挥着重要作用,实现了对水库实时水位、流量等数据的采集监控,为水利工程安全提供了可

    2024年04月26日
    浏览(41)
  • 速动资产包括哪些(速动资产和流动资产)

    速动资产包括货币资金、交易性金融资产和各种应收款项等。速动资产指的是会计账目上流动资产扣除存货和待摊费用后的余额,主要包括货币资金、短期投资、应收票据、应收账款等各项可迅速变现的资产。流动资产是指企业可以在一年或者超过一年的一个营业周期内变现

    2024年02月09日
    浏览(53)
  • 校园跑腿小程序都包括哪些业务呢?

    校园创业,大家都知道,一直以来是个非常火热的话题,每位步入大学校园的学子们都有过在校创业的想法,包括我们一些有着学校资源的社会创业者们,早已经看好了中国高校这块巨大的市场。 在这里,我要跟大家分享几个数据,截止到2023年,全国高等院校已经达3072所,

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包