<PackageReference Include="NUnit" Version="4.3.0" />

StringTokenEnumerator

Allows enumerating sub-strings from a string based on separator char. Basically a less allocating version of string.Split.
using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace NUnit.Framework.Internal { [NullableContext(1)] [Nullable(0)] internal struct StringTokenEnumerator : IEnumerator<string>, IEnumerator, IDisposable, IEnumerable { private readonly string _target; private readonly char _separator; private readonly bool _returnEmptyTokens; private int _currentStartIndex; private bool _finised; public string Current { [IsReadOnly] get; private set; } object IEnumerator.Current { get { return Current; } } public StringTokenEnumerator(string target, char separator, bool returnEmptyTokens) { _currentStartIndex = 0; _target = target; _separator = separator; _returnEmptyTokens = returnEmptyTokens; _finised = false; Current = string.Empty; } public bool MoveNext() { if (!_returnEmptyTokens && _target.Length == 0) return false; while (FindNextToken() && !_returnEmptyTokens && Current.Length == 0) { } return !_finised; } private bool FindNextToken() { int currentStartIndex = _currentStartIndex; if (currentStartIndex > _target.Length) { _finised = true; return false; } int num = _target.IndexOf(_separator, currentStartIndex); if (num == -1) { Current = _target.Substring(currentStartIndex); _currentStartIndex = _target.Length + 1; return true; } Current = _target.Substring(currentStartIndex, num - currentStartIndex); _currentStartIndex = num + 1; return true; } public void Reset() { throw new NotSupportedException("Resetting enumerator is not supported"); } public void Dispose() { } public StringTokenEnumerator GetEnumerator() { return this; } IEnumerator IEnumerable.GetEnumerator() { return this; } } }