我正在用这种类型尝试一些东西Span<T>
。我的目标是创建一个扩展方法来枚举 a 的拆分ReadOnlySpan<char>
,用法如下:
var x = "foo,bar,baz".AsSpan();
var options = StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries;
foreach (var word in x.EnumerateSplit(',', options))
{
// Should enumerate foo, bar and baz
}
但是,当我实现自己的枚举器类型(在Span<Range>.Enumerator
后台封装实例)时,IndexOutOfRangeException
在访问封装的枚举器Current
属性时会抛出 an 。
我尝试创建最基本的枚举器,它只有封装逻辑,没有分割机制:
public ref struct BasicEnumerator
{
// Encapsulated enumerator
private readonly Span<Range>.Enumerator _enumerator;
public Range Current => _enumerator.Current;
public BasicEnumerator(Span<Range>.Enumerator enumerator)
{
_enumerator = enumerator;
}
public bool MoveNext() => _enumerator.MoveNext();
// Called by foreach
public BasicEnumerator GetEnumerator() => this;
}
对于这种BasicEnumerator
类型,我至少期望这段代码能够工作:
Span<Range> test = stackalloc Range[5];
var enumerator = new BasicEnumerator(test.GetEnumerator());
foreach (Range r in enumerator)
{
Console.WriteLine(r);
}
但IndexOutOfRangeException
在第一次迭代时抛出了 an 。
我还尝试了更简单的方法而不使用foreach
:
Span<Range> test = stackalloc Range[5];
var enumerator = new BasicEnumerator(test.GetEnumerator());
if (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
IndexOutOfRangeException
尝试访问时仍会抛出enumerator.Current
。
请注意,当我使用Span<Range>.Enumerator
(以相同的方式)代替时,它会起作用:
Span<Range> test = stackalloc Range[5];
Span<Range>.Enumerator enumerator = test.GetEnumerator();
if (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
在调试时,我发现它不起作用,因为该Span<Range>.Enumerator.MoveNext
方法不会增加底层索引,但仍然返回true
:
Visual Studio 调试屏幕截图
我真的不知道为什么要这样做。我想说这是一个参考问题,但我不知道为什么以及如何解决它。我试图找到有关类似用例的文档,但没有成功。
我正在使用.NET 8。