@@ -72,3 +72,103 @@ class SentryItemTypeSerializationTest {
7272 return SentryItemType .Deserializer ().deserialize(reader, fixture.logger)
7373 }
7474}
75+
76+
77+
78+ ## 1 . ** Sentinel Object Pattern **
79+
80+ ```dart
81+ // Create a private sentinel marker
82+ const _undefined = Object ();
83+
84+ static Span startSpan(String name, {
85+ Map <String , SentryAttribute >? attributes,
86+ Object ? parentSpan = _undefined , // Uses Object? to accept Span?, null, or undefined
87+ bool active = true ,
88+ }) {
89+ final Span ? actualParentSpan;
90+ if (identical(parentSpan, _undefined )) {
91+ // Not provided - use default behavior (e.g., get from current scope)
92+ actualParentSpan = _getCurrentSpan ();
93+ } else {
94+ // Explicitly provided (could be null or a Span)
95+ actualParentSpan = parentSpan as Span ? ;
96+ }
97+ // ...
98+ }
99+ ```
100+
101+ ## 2 . ** Wrapper Class (Optional / Maybe )**
102+
103+ ```dart
104+ class Optional <T > {
105+ final T ? value;
106+ final bool isSet;
107+
108+ const Optional .absent() : value = null , isSet = false ;
109+ const Optional .of(this .value) : isSet = true ;
110+ }
111+
112+ static Span startSpan(String name, {
113+ Optional <Span > parentSpan = const Optional .absent(),
114+ }) {
115+ if (parentSpan.isSet) {
116+ // Explicitly provided (value could be null or a Span)
117+ } else {
118+ // Not provided
119+ }
120+ }
121+ ```
122+
123+ ## 3 . ** Sealed Classes (Dart 3 + )** — Most Type - Safe
124+
125+ ```dart
126+ sealed class ParentSpanOption {}
127+ class UseCurrentSpan extends ParentSpanOption {} // undefined - use default
128+ class ExplicitSpan extends ParentSpanOption {
129+ final Span ? span; // can be null or a span
130+ ExplicitSpan (this .span);
131+ }
132+
133+ static Span startSpan(String name, {
134+ ParentSpanOption parentSpan = const UseCurrentSpan (),
135+ }) {
136+ switch (parentSpan) {
137+ case UseCurrentSpan ():
138+ // Not provided - use default behavior
139+ case ExplicitSpan (span: final span):
140+ // Explicitly provided (span or null)
141+ }
142+ }
143+ ```
144+
145+ ## 4 . ** Separate Boolean Flag **
146+
147+ ```dart
148+ static Span startSpan(String name, {
149+ Span ? parentSpan,
150+ bool parentSpanProvided = false , // true means parentSpan was explicitly set
151+ bool active = true ,
152+ }) {
153+ if (parentSpanProvided) {
154+ // Use parentSpan (even if null)
155+ } else {
156+ // Not provided - use default
157+ }
158+ }
159+ ```
160+
161+ ## 5 . ** Record Type (Dart 3 + )**
162+
163+ ```dart
164+ static Span startSpan(String name, {
165+ (bool isSet, Span ? value)? parentSpan, // null = undefined, (true, x) = explicit
166+ }) {
167+ if (parentSpan == null ) {
168+ // undefined
169+ } else {
170+ final (_, span) = parentSpan;
171+ // explicitly set to `span` (which could be null)
172+ }
173+ }
174+ ```
0 commit comments