gpt4 book ai didi

c# - 我可以在不复制 C# 8 中的元素的情况下遍历结构数组吗?

转载 作者:太空狗 更新时间:2023-10-29 23:12:08 29 4
gpt4 key购买 nike

有了新的readonly instance member features in C# 8 ,我尝试减少代码中不必要的结构实例复制。

根据 this answer,我确实对结构数组进行了一些 foreach 迭代,这意味着在遍历数组时复制每个元素。

我想我现在可以简单地修改我的代码来防止复制,就像这样:

// Example struct, real structs may be even bigger than 32 bytes.
struct Color
{
public int R;
public int G;
public int B;
public int A;
}

class Program
{
static void Main()
{
Color[] colors = new Color[128];
foreach (ref readonly Color color in ref colors) // note 'ref readonly' placed here
Debug.WriteLine($"Color is {color.R} {color.G} {color.B} {color.A}.");
}
}

遗憾的是,这不能编译

CS1510  A ref or out value must be an assignable variable

但是,使用这样的索引器编译:

static void Main()
{
Color[] colors = new Color[128];
for (int i = 0; i < colors.Length; i++)
{
ref readonly Color color = ref colors[i];
Debug.WriteLine($"Color is {color.R} {color.G} {color.B} {color.A}.");
}
}

我在 foreach 替代方案中的语法是错误的,还是这在 C# 8 中根本不可能(可能是因为枚举是如何在内部实现的)?还是 C# 8 现在应​​用了一些智能,不再自行复制 Color 实例?

最佳答案

foreach 基于目标类型的定义而不是一些内部黑盒工作。我们可以利用它来创建引用枚举支持:

//using System;

public readonly struct ArrayEnumerableByRef<T>
{
private readonly T[] _target;

public ArrayEnumerableByRef(T[] target) => _target = target;

public Enumerator GetEnumerator() => new Enumerator(_target);

public struct Enumerator
{
private readonly T[] _target;

private int _index;

public Enumerator(T[] target)
{
_target = target;
_index = -1;
}

public readonly ref T Current
{
get
{
if (_target is null || _index < 0 || _index > _target.Length)
{
throw new InvalidOperationException();
}
return ref _target[_index];
}
}

public bool MoveNext() => ++_index < _target.Length;

public void Reset() => _index = -1;
}
}

public static class ArrayExtensions
{
public static ArrayEnumerableByRef<T> ToEnumerableByRef<T>(this T[] array) => new ArrayEnumerableByRef<T>(array);
}

然后我们可以通过引用通过foreach循环枚举一个数组:

static void Main()
{
var colors = new Color[128];

foreach (ref readonly var color in colors.ToEnumerableByRef())
{
Debug.WriteLine($"Color is {color.R} {color.G} {color.B} {color.A}.");
}
}

关于c# - 我可以在不复制 C# 8 中的元素的情况下遍历结构数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58069669/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com