亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C# 二進制數(shù)組與結構體的互轉方法

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

本文將告訴大家在 dotnet 里面的二進制基礎處理知識,如何在 C# 里面將結構體數(shù)組和二進制數(shù)組進行相互轉換的簡單方法

盡管本文屬于基礎入門的知識,但是在閱讀之前還請自行了解 C# 里面的結構體內存布局知識

本文將和大家介紹 MemoryMarshal 輔助類,通過這個輔助類用來實現(xiàn)結構體數(shù)組和二進制數(shù)組的相互轉換

先演示如何從結構體數(shù)組和二進制數(shù)組的相互轉換。準確來說是 Span 之間的相互轉換,而不是真的轉換為數(shù)組,只是 Span 的行為表現(xiàn)和數(shù)組十分相似

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

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

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

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

拿到 Foo1 的數(shù)組之后,可以非常方便轉換為 Span 類型,只需要調用 foo1Array.AsSpan() 即可。接下來將 Foo1 數(shù)組轉化在二進制數(shù)組,準確來說是 Span<byte> 類型,代碼如下

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

此時編寫一個輔助方法,將 foo1ByteSpan 的內容輸出到控制臺,方便讓大家看到這個 foo1ByteSpan 對象就確實是 Foo1 結構體的內存空間的二進制內容

        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 就是對應 Foo1 結構體的 A 和 B 和 C 屬性的值。本文這里沒有對 Foo1 結構體進行固定布局等,這一點不夠嚴謹,也就是說我只能和大家保證一定出現(xiàn) Foo1 結構體的 A 和 B 和 C 屬性的值,但是不能保證這些值出現(xiàn)的順序。如果不了解這部分的知識,還請自行查閱 dotnet 里面的結構體的內存布局優(yōu)化和內存對齊

接下來開始證明本文以上拿到的 foo1ByteSpan 和 foo1Array 指向相同的一片內存地址空間,也就是對 foo1Array 或 foo1ByteSpan 的內存修改,都會相互影響

先修改 foo1Array 里面的內容,比如修改一個屬性的內容,如以下代碼

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

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

再嘗試修改 foo1ByteSpan 的內容,看看是否也能反過來影響到 foo1Array 對象

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

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

通過 MemoryMarshal.Cast 方法,不僅可以支持結構體和 byte 之間的轉換,也可以進行結構體之間的轉換,比如再定義一個 Foo2 類型,這個 Foo2 類型和 Foo1 類型有相同的屬性只是類型不相同而已,試試使用以下代碼進行相互轉換

        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; }
}

可以看到通過 MemoryMarshal.Cast 是可以實現(xiàn)多個結構體之間的直接轉換的,且沒有重新在堆上重新開辟數(shù)組空間

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

本文的代碼放在github 和 gitee 歡迎訪問

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

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

以上使用的是 gitee 的源,如果 gitee 不能訪問,請?zhí)鎿Q為 github 的源。請在命令行繼續(xù)輸入以下代碼

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

獲取代碼之后,進入 HallehuwearjewhoQedelqarnalar 文件夾

到此這篇關于C# 二進制數(shù)組與結構體的互轉的文章就介紹到這了,更多相關C# 二進制數(shù)組與結構體互轉內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C#生成設置范圍內的Double類型隨機數(shù)的方法

    C#生成設置范圍內的Double類型隨機數(shù)的方法

    這篇文章主要介紹了C#生成設置范圍內的Double類型隨機數(shù)的方法,對于C#的初學者有很好的借鑒價值,需要的朋友可以參考下
    2014-08-08
  • 深入理解C# 委托與事件

    深入理解C# 委托與事件

    本文主要介紹了深入理解C# 委托與事件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2008-05-05
  • 詳解c# 并行計算

    詳解c# 并行計算

    本文主要介紹了并行計算的簡單使用,并行循環(huán)的中斷和跳出、并行循環(huán)中為數(shù)組/集合添加項、返回集合運算結果/含有局部變量的并行循環(huán)、、PLinq(Linq的并行計算)等相關內容。
    2020-12-12
  • C#使用FileInfo和DirectoryInfo類來執(zhí)行文件和文件夾操作

    C#使用FileInfo和DirectoryInfo類來執(zhí)行文件和文件夾操作

    System.IO.FileInfo?和?System.IO.DirectoryInfo?是C#中用于操作文件和文件夾的類,它們提供了許多有用的方法和屬性來管理文件和文件夾,這篇文章主要介紹了C#使用FileInfo和DirectoryInfo類來執(zhí)行文件和文件夾操作,需要的朋友可以參考下
    2023-08-08
  • 用幾行C#代碼實現(xiàn)定時關機/重啟(超詳細!建議新手練習)

    用幾行C#代碼實現(xiàn)定時關機/重啟(超詳細!建議新手練習)

    有很多的軟件都實現(xiàn)了自動關機這樣的功能,下面這篇文章主要給大家介紹了關于利用幾行C#代碼實現(xiàn)定時關機/重啟的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • Unity圖形學之ShaderLab入門基礎

    Unity圖形學之ShaderLab入門基礎

    Unity中所有Shader文件都通過一種陳述性語言進行描述,稱為“ShaderLab”, 這篇文章主要介紹了Unity圖形學之ShaderLab入門基礎,需要的朋友可以參考下
    2022-01-01
  • 精簡高效的C#網站優(yōu)化經驗技巧總結

    精簡高效的C#網站優(yōu)化經驗技巧總結

    這篇文章主要為大家介紹了精簡高效的C#網站優(yōu)化經驗技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • Unity Shader實現(xiàn)徑向模糊效果

    Unity Shader實現(xiàn)徑向模糊效果

    這篇文章主要為大家詳細介紹了Unity Shader實現(xiàn)徑向模糊效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C# 使用動態(tài)庫DllImport("kernel32")讀寫ini文件的步驟

    C# 使用動態(tài)庫DllImport("kernel32")讀寫ini文件的步驟

    kernel32.dll是Windows中非常重要的32位動態(tài)鏈接庫文件,屬于內核級文件,這篇文章主要介紹了C# 利用動態(tài)庫DllImport("kernel32")讀寫ini文件,需要的朋友可以參考下
    2023-05-05
  • Unity Shader實現(xiàn)翻書效果

    Unity Shader實現(xiàn)翻書效果

    這篇文章主要為大家詳細介紹了Unity Shader實現(xiàn)翻書效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評論