最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# 二進(jìn)制數(shù)組與結(jié)構(gòu)體的互轉(zhuǎn)方法

 更新時(shí)間:2023年09月05日 09:06:34   作者:lindexi  
本文將和大家介紹 MemoryMarshal 輔助類(lèi),通過(guò)這個(gè)輔助類(lèi)用來(lái)實(shí)現(xiàn)結(jié)構(gòu)體數(shù)組和二進(jìn)制數(shù)組的相互轉(zhuǎn)換,對(duì)C# 二進(jìn)制數(shù)組與結(jié)構(gòu)體的互轉(zhuǎn)方法感興趣的朋友一起看看吧

本文將告訴大家在 dotnet 里面的二進(jìn)制基礎(chǔ)處理知識(shí),如何在 C# 里面將結(jié)構(gòu)體數(shù)組和二進(jìn)制數(shù)組進(jìn)行相互轉(zhuǎn)換的簡(jiǎn)單方法

盡管本文屬于基礎(chǔ)入門(mén)的知識(shí),但是在閱讀之前還請(qǐng)自行了解 C# 里面的結(jié)構(gòu)體內(nèi)存布局知識(shí)

本文將和大家介紹 MemoryMarshal 輔助類(lèi),通過(guò)這個(gè)輔助類(lèi)用來(lái)實(shí)現(xiàn)結(jié)構(gòu)體數(shù)組和二進(jìn)制數(shù)組的相互轉(zhuǎn)換

先演示如何從結(jié)構(gòu)體數(shù)組和二進(jìn)制數(shù)組的相互轉(zhuǎn)換。準(zhǔn)確來(lái)說(shuō)是 Span 之間的相互轉(zhuǎn)換,而不是真的轉(zhuǎn)換為數(shù)組,只是 Span 的行為表現(xiàn)和數(shù)組十分相似

為了方便代碼演示,我定義了一個(gè) Foo1 的結(jié)構(gòu)體,本文的全部代碼都可以在本文末尾找到下載方法

struct Foo1
{
    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
}

先創(chuàng)建出一個(gè) Foo1 結(jié)構(gòu)體數(shù)組,為了方便演示我還給 Foo1 的各個(gè)屬性分別賦值,如以下代碼

        var foo1 = new Foo1()
        {
            A = 1,
            B = 2,
            C = 3,
        };
        var foo1Array = new Foo1[] { foo1 };

拿到 Foo1 的數(shù)組之后,可以非常方便轉(zhuǎn)換為 Span 類(lèi)型,只需要調(diào)用 foo1Array.AsSpan() 即可。接下來(lái)將 Foo1 數(shù)組轉(zhuǎn)化在二進(jìn)制數(shù)組,準(zhǔn)確來(lái)說(shuō)是 Span<byte> 類(lèi)型,代碼如下

        Span<byte> foo1ByteSpan = MemoryMarshal.AsBytes(foo1Array.AsSpan());

此時(shí)編寫(xiě)一個(gè)輔助方法,將 foo1ByteSpan 的內(nèi)容輸出到控制臺(tái),方便讓大家看到這個(gè) foo1ByteSpan 對(duì)象就確實(shí)是 Foo1 結(jié)構(gòu)體的內(nèi)存空間的二進(jìn)制內(nèi)容

        Log(foo1ByteSpan); // 01 00 00 00 02 00 00 00 03 00 00 00
    private static void Log(Span<byte> byteSpan)
    {
        var stringBuilder = new StringBuilder();
        foreach (var b in byteSpan)
        {
            stringBuilder.Append(b.ToString("X2"));
            stringBuilder.Append(' ');
        }
        Console.WriteLine(stringBuilder.ToString());
    }

可以看到以上輸出的 01 02 03 就是對(duì)應(yīng) Foo1 結(jié)構(gòu)體的 A 和 B 和 C 屬性的值。本文這里沒(méi)有對(duì) Foo1 結(jié)構(gòu)體進(jìn)行固定布局等,這一點(diǎn)不夠嚴(yán)謹(jǐn),也就是說(shuō)我只能和大家保證一定出現(xiàn) Foo1 結(jié)構(gòu)體的 A 和 B 和 C 屬性的值,但是不能保證這些值出現(xiàn)的順序。如果不了解這部分的知識(shí),還請(qǐng)自行查閱 dotnet 里面的結(jié)構(gòu)體的內(nèi)存布局優(yōu)化和內(nèi)存對(duì)齊

接下來(lái)開(kāi)始證明本文以上拿到的 foo1ByteSpan 和 foo1Array 指向相同的一片內(nèi)存地址空間,也就是對(duì) foo1Array 或 foo1ByteSpan 的內(nèi)存修改,都會(huì)相互影響

先修改 foo1Array 里面的內(nèi)容,比如修改一個(gè)屬性的內(nèi)容,如以下代碼

        foo1Array[0].C = 5;
        Log(foo1ByteSpan); // 01 00 00 00 02 00 00 00 05 00 00 00

可以看到修改了 C 屬性之后,打印出的 foo1ByteSpan 也更改了

再?lài)L試修改 foo1ByteSpan 的內(nèi)容,看看是否也能反過(guò)來(lái)影響到 foo1Array 對(duì)象

        foo1ByteSpan[0] = 6;
        Console.WriteLine(foo1Array[0].A); // 6
        var foo1Span = MemoryMarshal.Cast<byte, Foo1>(foo1ByteSpan);
        Console.WriteLine(foo1Span[0].A); // 6

通過(guò)以上代碼即可證明了 foo1ByteSpan 和 foo1Array 指向相同的一片內(nèi)存地址空間,也就是 MemoryMarshal.Cast 和 MemoryMarshal.AsBytes 不是重新申請(qǐng)一片內(nèi)存空間存放數(shù)組內(nèi)容,而是僅僅編寫(xiě)的代碼上的魔法,內(nèi)存都是相同的一片空間。如此減少了內(nèi)存空間轉(zhuǎn)換拷貝,可以極大的提升性能,同時(shí)也兼顧了安全性

通過(guò) MemoryMarshal.Cast 方法,不僅可以支持結(jié)構(gòu)體和 byte 之間的轉(zhuǎn)換,也可以進(jìn)行結(jié)構(gòu)體之間的轉(zhuǎn)換,比如再定義一個(gè) Foo2 類(lèi)型,這個(gè) Foo2 類(lèi)型和 Foo1 類(lèi)型有相同的屬性只是類(lèi)型不相同而已,試試使用以下代碼進(jìn)行相互轉(zhuǎn)換

        var foo2Span = MemoryMarshal.Cast<Foo1, Foo2>(foo1Span);
        Console.WriteLine(foo2Span[0].A); // 6
        Console.WriteLine(foo2Span[0].B); // 2
        Console.WriteLine(foo2Span[0].C); // 5
struct Foo2
{
    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
}

可以看到通過(guò) MemoryMarshal.Cast 是可以實(shí)現(xiàn)多個(gè)結(jié)構(gòu)體之間的直接轉(zhuǎn)換的,且沒(méi)有重新在堆上重新開(kāi)辟數(shù)組空間

但是本文以上的代碼是不嚴(yán)謹(jǐn)?shù)?,以上代碼沒(méi)有固定 Foo1 結(jié)構(gòu)體和 Foo2 結(jié)構(gòu)體的內(nèi)存布局,以上的代碼只是用來(lái)告訴大家 MemoryMarshal.Cast 的用法,而不是推薦大家在正式的項(xiàng)目跟隨我這么寫(xiě)。如果在正式項(xiàng)目里面,需要確保多個(gè)結(jié)構(gòu)體之間的內(nèi)存布局相同或者是在各個(gè)情況下的直接內(nèi)存轉(zhuǎn)換是符合預(yù)期的才能這么做

本文的代碼放在github 和 gitee 歡迎訪問(wèn)

可以通過(guò)如下方式獲取本文的源代碼,先創(chuàng)建一個(gè)空文件夾,接著使用命令行 cd 命令進(jìn)入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 6bd28ceca1e9b73bfda270f9a3a3bddd7b8ebcc4

以上使用的是 gitee 的源,如果 gitee 不能訪問(wèn),請(qǐng)?zhí)鎿Q為 github 的源。請(qǐng)?jiān)诿钚欣^續(xù)輸入以下代碼

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 6bd28ceca1e9b73bfda270f9a3a3bddd7b8ebcc4

獲取代碼之后,進(jìn)入 HallehuwearjewhoQedelqarnalar 文件夾

到此這篇關(guān)于C# 二進(jìn)制數(shù)組與結(jié)構(gòu)體的互轉(zhuǎn)的文章就介紹到這了,更多相關(guān)C# 二進(jìn)制數(shù)組與結(jié)構(gòu)體互轉(zhuǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C#中yield關(guān)鍵字的用法

    詳解C#中yield關(guān)鍵字的用法

    yield?關(guān)鍵字的用途是把指令推遲到程序?qū)嶋H需要的時(shí)候再執(zhí)行,這個(gè)特性允許我們更細(xì)致地控制集合每個(gè)元素產(chǎn)生的時(shí)機(jī),那么下面就一起來(lái)看下怎么用?yield?關(guān)鍵字吧
    2023-07-07
  • C#利用VS中插件打包并發(fā)布winfrom程序

    C#利用VS中插件打包并發(fā)布winfrom程序

    這篇文章主要為大家詳細(xì)介紹了C#利用VS中插件打包并發(fā)布winfrom程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • WPF數(shù)據(jù)綁定時(shí)出現(xiàn)StringFormat失效的原因和解決方法

    WPF數(shù)據(jù)綁定時(shí)出現(xiàn)StringFormat失效的原因和解決方法

    在數(shù)據(jù)綁定過(guò)程中,我們經(jīng)常會(huì)使用StringFormat對(duì)要顯示的數(shù)據(jù)進(jìn)行格式化,以便獲得更為直觀的展示效果,但在某些情況下格式化操作并未生效,所以本文介紹了WPF數(shù)據(jù)綁定時(shí)出現(xiàn)StringFormat失效的原因和解決方法,需要的朋友可以參考下
    2024-12-12
  • C#中調(diào)整圖像大小的步驟詳解

    C#中調(diào)整圖像大小的步驟詳解

    這篇文章主要介紹了C#中調(diào)整圖像大小的步驟詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • c# 兩種發(fā)送郵件的方法

    c# 兩種發(fā)送郵件的方法

    這篇文章主要介紹了c# 兩種發(fā)送郵件的方法,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-04-04
  • C#處理TCP數(shù)據(jù)的方法詳解

    C#處理TCP數(shù)據(jù)的方法詳解

    Tcp是一個(gè)面向連接的流數(shù)據(jù)傳輸協(xié)議,用人話(huà)說(shuō)就是傳輸是一個(gè)已經(jīng)建立好連接的管道,數(shù)據(jù)都在管道里像流水一樣流淌到對(duì)端,那么數(shù)據(jù)必然存在幾個(gè)問(wèn)題,比如數(shù)據(jù)如何持續(xù)的讀取,數(shù)據(jù)包的邊界等,本文給大家介紹了C#處理TCP數(shù)據(jù)的方法,需要的朋友可以參考下
    2024-06-06
  • c# 使用Json.NET實(shí)現(xiàn)json序列化

    c# 使用Json.NET實(shí)現(xiàn)json序列化

    這篇文章主要介紹了詳解C#中的JSON序列化方法,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-05-05
  • C#面向?qū)ο髮?shí)現(xiàn)圖書(shū)管理系統(tǒng)

    C#面向?qū)ο髮?shí)現(xiàn)圖書(shū)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C#面向?qū)ο髮?shí)現(xiàn)圖書(shū)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 使用C#實(shí)現(xiàn)在Excel中創(chuàng)建和配置數(shù)據(jù)透視表

    使用C#實(shí)現(xiàn)在Excel中創(chuàng)建和配置數(shù)據(jù)透視表

    在數(shù)據(jù)分析和業(yè)務(wù)報(bào)告場(chǎng)景中,數(shù)據(jù)透視表(Pivot?Table)是一種強(qiáng)大的數(shù)據(jù)匯總工具,本文將介紹如何使用?C#?在?Excel?工作表中創(chuàng)建和配置數(shù)據(jù)透視表,感興趣的小伙伴可以了解下
    2026-03-03
  • 使用快捷鍵在Unity中快速鎖定和解鎖Inspector右上角的鎖功能

    使用快捷鍵在Unity中快速鎖定和解鎖Inspector右上角的鎖功能

    這篇文章主要為大家介紹了使用快捷鍵在Unity中快速鎖定和解鎖Inspector右上角的鎖功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08

最新評(píng)論

徐水县| 禹城市| 克拉玛依市| 通道| 新余市| 烟台市| 滦平县| 克什克腾旗| 吉木乃县| 凤台县| 个旧市| 兴安县| 繁昌县| 惠安县| 淅川县| 桃江县| 通辽市| 佛冈县| 元氏县| 盖州市| 新密市| 天气| 宿松县| 志丹县| 洪江市| 大港区| 无锡市| 云南省| 永年县| 大厂| 镇坪县| 乐平市| 驻马店市| 郴州市| 城固县| 麻阳| 松桃| 巢湖市| 汉源县| 临漳县| 嫩江县|