@@ -16,6 +16,10 @@ internal static class ActivityEnumerationHelper
1616{
1717 private static AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , object ? > > , KeyValuePair < string , object ? > , OtelTagsEnumerationState > . AllocationFreeForEachDelegate ? _tagObjectsEnumerator ;
1818 private static AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , string ? > > , KeyValuePair < string , string ? > , OtelTagsEnumerationState > . AllocationFreeForEachDelegate ? _tagsEnumerator ;
19+ #if DEBUG
20+ private static Type ? _tagObjectsType ;
21+ private static Type ? _tagType ;
22+ #endif
1923
2024 /// <summary>
2125 /// Returns an enumerator than can be used to iterate the provided <see cref="IActivity5.TagObjects"/>, without allocating.
@@ -26,27 +30,47 @@ internal static class ActivityEnumerationHelper
2630 public static AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , object ? > > , KeyValuePair < string , object ? > , OtelTagsEnumerationState > . AllocationFreeForEachDelegate GetTagObjectsEnumerator < T > ( T activity5 )
2731 where T : IActivity5
2832 {
33+ #if DEBUG
34+ // Tag type used to call this method should never change
35+ if ( Volatile . Read ( ref _tagObjectsType ) is { } expectedType )
36+ {
37+ System . Diagnostics . Debug . Assert ( expectedType == activity5 . TagObjects . GetType ( ) , "Must always call this method with the same type of TagObjects" ) ;
38+ }
39+ #endif
2940 return Volatile . Read ( ref _tagObjectsEnumerator ) ?? BuildDelegate ( activity5 ) ;
3041
3142 static AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , object ? > > , KeyValuePair < string , object ? > , OtelTagsEnumerationState > . AllocationFreeForEachDelegate BuildDelegate ( T activity5 )
3243 {
3344 var forEach = AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , object ? > > , KeyValuePair < string , object ? > , OtelTagsEnumerationState >
3445 . BuildAllocationFreeForEachDelegate ( activity5 . TagObjects . GetType ( ) ) ;
3546
47+ #if DEBUG
48+ Volatile . Write ( ref _tagObjectsType , activity5 . TagObjects . GetType ( ) ) ;
49+ #endif
3650 return Interlocked . CompareExchange ( ref _tagObjectsEnumerator , forEach , null ) ?? forEach ;
3751 }
3852 }
3953
4054 public static AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , string ? > > , KeyValuePair < string , string ? > , OtelTagsEnumerationState > . AllocationFreeForEachDelegate GetTagsEnumerator < T > ( T activity )
4155 where T : IActivity
4256 {
57+ #if DEBUG
58+ // Tag type used to call this method should never change
59+ if ( Volatile . Read ( ref _tagType ) is { } expectedType )
60+ {
61+ System . Diagnostics . Debug . Assert ( expectedType == activity . Tags . GetType ( ) , "Must always call this method with the same type of TagObjects" ) ;
62+ }
63+ #endif
4364 return Volatile . Read ( ref _tagsEnumerator ) ?? BuildDelegate ( activity ) ;
4465
4566 static AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , string ? > > , KeyValuePair < string , string ? > , OtelTagsEnumerationState > . AllocationFreeForEachDelegate BuildDelegate ( T activity )
4667 {
4768 var forEach = AllocationFreeEnumerator < IEnumerable < KeyValuePair < string , string ? > > , KeyValuePair < string , string ? > , OtelTagsEnumerationState >
4869 . BuildAllocationFreeForEachDelegate ( activity . Tags . GetType ( ) ) ;
4970
71+ #if DEBUG
72+ Volatile . Write ( ref _tagType , activity . Tags . GetType ( ) ) ;
73+ #endif
5074 return Interlocked . CompareExchange ( ref _tagsEnumerator , forEach , null ) ?? forEach ;
5175 }
5276 }
0 commit comments