using System.Buffers.Binary;
using System.Buffers.Text;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
{
#pragma warning disable CA1825 // Array.Empty<T>() doesn't exist in all configurations
private static readonly IEnumerable<KeyValuePair<string, string?>> s_emptyBaggageTags = new KeyValuePair<string, string?>[0];
+ private static readonly IEnumerable<KeyValuePair<string, object?>> s_emptyTagObjects = new KeyValuePair<string, object?>[0];
private static readonly IEnumerable<ActivityLink> s_emptyLinks = new ActivityLink[0];
private static readonly IEnumerable<ActivityEvent> s_emptyEvents = new ActivityEvent[0];
#pragma warning restore CA1825
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
- get => _tags?.Enumerate() ?? Unsafe.As<IEnumerable<KeyValuePair<string, object?>>>(s_emptyBaggageTags);
+ get => _tags ?? s_emptyTagObjects;
}
/// <summary>
/// </summary>
public IEnumerable<ActivityEvent> Events
{
- get => _events != null ? _events.Enumerate() : s_emptyEvents;
+ get => _events ?? s_emptyEvents;
}
/// <summary>
/// </summary>
public IEnumerable<ActivityLink> Links
{
- get => _links != null ? _links.Enumerate() : s_emptyLinks;
+ get => _links ?? s_emptyLinks;
}
/// <summary>
}
// We are not using the public LinkedList<T> because we need to ensure thread safety operation on the list.
- private class LinkedList<T>
+ private class LinkedList<T> : IEnumerable<T>
{
private LinkedListNode<T> _first;
private LinkedListNode<T> _last;
}
}
- public IEnumerable<T> Enumerate()
- {
- LinkedListNode<T>? current = _first;
- do
- {
- yield return current.Value;
- current = current.Next;
- } while (current != null);
- }
+ public Enumerator<T> GetEnumerator() => new Enumerator<T>(_first);
+ IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator<T>(_first);
+ IEnumerator IEnumerable.GetEnumerator() => new Enumerator<T>(_first);
}
- private class TagsLinkedList
+ private class TagsLinkedList : IEnumerable<KeyValuePair<string, object?>>
{
private LinkedListNode<KeyValuePair<string, object?>>? _first;
private LinkedListNode<KeyValuePair<string, object?>>? _last;
}
}
+ public Enumerator<KeyValuePair<string, object?>> GetEnumerator() => new Enumerator<KeyValuePair<string, object?>>(_first);
+ IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator() => new Enumerator<KeyValuePair<string, object?>>(_first);
+ IEnumerator IEnumerable.GetEnumerator() => new Enumerator<KeyValuePair<string, object?>>(_first);
+
public IEnumerable<KeyValuePair<string, string?>> EnumerateStringValues()
{
LinkedListNode<KeyValuePair<string, object?>>? current = _first;
{
if (current.Value.Value is string || current.Value.Value == null)
{
- yield return new KeyValuePair<string, string?>(current.Value.Key, (string?) current.Value.Value);
+ yield return new KeyValuePair<string, string?>(current.Value.Key, (string?)current.Value.Value);
}
current = current.Next;
};
}
+ }
- public IEnumerable<KeyValuePair<string, object?>> Enumerate()
+ private struct Enumerator<T> : IEnumerator<T>
+ {
+ private readonly LinkedListNode<T>? _head;
+ private LinkedListNode<T>? _nextNode;
+ [AllowNull, MaybeNull] private T _currentItem;
+
+ public Enumerator(LinkedListNode<T>? head)
{
- LinkedListNode<KeyValuePair<string, object?>>? current = _first;
+ _nextNode = _head = head;
+ _currentItem = default;
+ }
- while (current != null)
+ public T Current => _currentItem!;
+
+ object? IEnumerator.Current => Current;
+
+ public bool MoveNext()
+ {
+ if (_nextNode == null)
{
- yield return current.Value;
- current = current.Next;
- };
+ _currentItem = default;
+ return false;
+ }
+
+ _currentItem = _nextNode.Value;
+ _nextNode = _nextNode.Next;
+ return true;
+ }
+
+ public void Reset() => _nextNode = _head;
+
+ public void Dispose()
+ {
}
}