【发布时间】:2020-03-20 01:43:51
【问题描述】:
以下代码导致编译器在属性 getter 的第一行抛出错误 CS1605(“无法将 'var' 作为 ref 或 out 参数传递,因为它是只读的”)。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public readonly struct MyStruct
{
public readonly int Field1;
public readonly int Field2;
public MyStruct(int field1, int field2) => (Field1, Field2) = (field1, field2);
public ReadOnlySpan<byte> Span
{
get
{
// This code only works when MyStruct is not read only
ReadOnlySpan<MyStruct> temp = MemoryMarshal.CreateReadOnlySpan(ref this, 1);
return MemoryMarshal.Cast<MyStruct, byte>(temp);
}
}
}
从public readonly struct MyStruct 行中删除readonly 会使代码工作,但出于性能原因,我真的希望结构为readonly。它使代码比一直传递结构为ref 更简洁。
有没有办法从只读结构中获取ReadOnlySpan<byte>?
编辑: ... 不创建结构的隐式或显式副本?
【问题讨论】:
-
我认为你的意思是“ref struct”(它在堆栈上)。我认为“只读结构”不会给您带来任何性能提升。
-
我假设结构只是一个示例,但一般来说,您不想特意阻止复制 8 字节结构,因为指针只是一样大(在 64 位系统上),并且跳过间接可能会产生更好的代码。
Span和 co 的最大胜利是避免堆分配和复制大型数据结构,而不是避免复制小型数据结构(有更好的技术,比如将大量数据打包成数组)。当然,在任何情况下,它们都不会让代码“干净”——在性能分析表明重要的地方使用它们。 -
谢谢 Mario Vernari 和 Jeroen Mostert。实际的结构要大得多。我在内存映射文件中有数百万个这个结构的“实例”,我需要尽快访问它。