c# - 在 .C# 和 NET 5 中,在 struct 和 Span<byte> 之间进行无不安全的转换,反之亦然

标签 c# .net ref .net-5

我尝试将一个结构转换到 Span 并返回(以便可以更改原始结构)。这部分起作用了。如何将 Span 转换回结构体(不要复制)?

这是我的尝试。不幸的是,它在回传时不起作用:

internal struct TestStruct
{
    internal byte ByteValue;
    internal ushort UshortValue;
    internal uint UintValue;
    internal ulong UlongValue;

    internal TestStruct(byte byteValue,ushort ushortValue, uint uintValue, ulong ulongValue) {
        ByteValue = byteValue;
        UshortValue = ushortValue;
        UintValue = uintValue;
        UlongValue = ulongValue;
    }
}

class Program
{
    static void Main(string[] args) {
        TestStruct structInstance = new TestStruct( 0xAA, 0xAAAA, 0xAAAAAAAA, 0xAAAAAAAAAAAAAAAA );            
        var span1 = MemoryMarshal.CreateSpan<TestStruct>(ref structInstance, 1);
        span1[0].ByteValue = 0x11;
        Debug.WriteLine($"span1[0].ByteValue = 0x11 => 0x{structInstance.ByteValue:X2}");
        var byteSpan1 = MemoryMarshal.AsBytes<TestStruct>(span1);
        byteSpan1[0] = 0x22;
        Debug.WriteLine($"byteSpan1[0] = 0x22 => 0x{structInstance.ByteValue:X2}");
        TestStruct structAgain = MemoryMarshal.AsRef<TestStruct>(byteSpan1);
        structAgain.ByteValue = 0xBB;
        Debug.WriteLine($"structAgain.ByteValue = 0xBB => 0x{structInstance.ByteValue:X2}");
    }
}

结果:

span1[0].ByteValue = 0x11 => 0x11
byteSpan1[0] = 0x22 => 0x22
structAgain.ByteValue = 0xBB => 0x22

显然MemoryMarshal.AsRef()给出了一个副本并且没有强制转换。有办法让它工作吗?

最佳答案

您遇到的问题是struct是一个值类型。这意味着,每个结构体字段/参数/局部变量都包含该结构体的整个值。您的TestStruct structAgain是您原件 structInstance 的独立副本。对副本的更改不会影响原始版本,反之亦然。

您想要的是对原始结构的引用。为此,您需要 ref关键词。如果你看MemoryMarshal.AsRef ,你看到返回类型是 ref T 。这意味着它正在返回一个引用。您可以通过将局部变量声明为ref TestStruct structAgain = ref MemoryMarshal.AsRef<TestStruct>(byteSpan1);来保存引用。 。现在 structAgain 不再是副本,而是对原始版本的引用。

关于c# - 在 .C# 和 NET 5 中,在 struct 和 Span<byte> 之间进行无不安全的转换,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66068340/

相关文章:

c# - ASP.NET Core 和 ActionFilter

c# - 回发时输入文本返回 NULL?

c# - Visual Studio 中的程序集引用问题

c# - 将 Jalali 月份添加到 Jalali 日期

c# - C# 中的设计时间序列化

c# - 如何将符号(英镑、欧元、版权)插入文本框

c# - 按特定顺序排序的列表

c# - 是否可以采取变通方法通过 ref 传递属性?加上路过引用事件

reactjs - useRef 不起作用 [TypeError : null is not an object (evaluating 'filed2.current.focus' )]

controller - Sencha Touch 2.1 通过 Controller 中的引用获取 View