@@ -176,5 +176,97 @@ public object Validate(object value)
176176 }
177177 return value ;
178178 }
179+
180+ /// <summary>
181+ /// Returns an equality comparer for <see cref="CloudEventAttribute"/> values that just uses the attribute name
182+ /// for equality comparisons. Validators, types and kinds (optional, required, extension) are not included in the comparison.
183+ /// </summary>
184+ public static IEqualityComparer < CloudEventAttribute > NameComparer { get ; } = new NameComparerImpl ( ) ;
185+
186+ /// <summary>
187+ /// Returns an equality comparer for <see cref="CloudEventAttribute"/> values that just uses the attribute name
188+ /// and type for equality comparisons. Validators and kinds (optional, required, extension) are not included in the comparison.
189+ /// </summary>
190+ public static IEqualityComparer < CloudEventAttribute > NameTypeComparer { get ; } = new NameTypeComparerImpl ( ) ;
191+
192+ /// <summary>
193+ /// Returns an equality comparer for <see cref="CloudEventAttribute"/> values that uses the attribute name,
194+ /// type and kind (optional, required, extension) for equality comparisons. Validators are not included in the comparison.
195+ /// </summary>
196+ public static IEqualityComparer < CloudEventAttribute > NameTypeKindComparer { get ; } = new NameTypeKindComparerImpl ( ) ;
197+
198+ /// <summary>
199+ /// Base class for all comparers, just to avoid having to worry about nullity in every implementation.
200+ /// </summary>
201+ private abstract class ComparerBase : IEqualityComparer < CloudEventAttribute >
202+ {
203+ public bool Equals ( CloudEventAttribute x , CloudEventAttribute y ) =>
204+ ( x is null && y is null ) ||
205+ ( x is not null && y is not null && EqualsImpl ( x , y ) ) ;
206+
207+ public int GetHashCode ( CloudEventAttribute obj )
208+ {
209+ Validation . CheckNotNull ( obj , nameof ( obj ) ) ;
210+ return GetHashCodeImpl ( obj ) ;
211+ }
212+
213+ protected abstract bool EqualsImpl ( CloudEventAttribute x , CloudEventAttribute y ) ;
214+ protected abstract int GetHashCodeImpl ( CloudEventAttribute obj ) ;
215+ }
216+
217+ private sealed class NameComparerImpl : ComparerBase
218+ {
219+ protected override bool EqualsImpl ( CloudEventAttribute x , CloudEventAttribute y ) => x . Name == y . Name ;
220+
221+ protected override int GetHashCodeImpl ( CloudEventAttribute obj ) => obj . Name . GetHashCode ( ) ;
222+ }
223+
224+ private sealed class NameTypeComparerImpl : ComparerBase
225+ {
226+ protected override bool EqualsImpl ( CloudEventAttribute x , CloudEventAttribute y ) =>
227+ x . Name == y . Name &&
228+ x . Type == y . Type ;
229+
230+ protected override int GetHashCodeImpl ( CloudEventAttribute obj )
231+ {
232+ #if NETSTANDARD2_1_OR_GREATER
233+ return HashCode . Combine ( obj . Name , obj . Type ) ;
234+ #else
235+ unchecked
236+ {
237+ int hash = 19 ;
238+ hash = hash * 31 + obj . Name . GetHashCode ( ) ;
239+ hash = hash * 31 + obj . Type . GetHashCode ( ) ;
240+ return hash ;
241+ }
242+ #endif
243+ }
244+ }
245+
246+ private sealed class NameTypeKindComparerImpl : ComparerBase
247+ {
248+ protected override bool EqualsImpl ( CloudEventAttribute x , CloudEventAttribute y ) =>
249+ x . Name == y . Name &&
250+ x . Type == y . Type &&
251+ x . IsExtension == y . IsExtension &&
252+ x . IsRequired == y . IsRequired ;
253+
254+ protected override int GetHashCodeImpl ( CloudEventAttribute obj )
255+ {
256+ #if NETSTANDARD2_1_OR_GREATER
257+ return HashCode . Combine ( obj . Name , obj . Type , obj . IsExtension , obj . IsRequired ) ;
258+ #else
259+ unchecked
260+ {
261+ int hash = 19 ;
262+ hash = hash * 31 + obj . Name . GetHashCode ( ) ;
263+ hash = hash * 31 + obj . Type . GetHashCode ( ) ;
264+ hash = hash * 31 + obj . IsExtension . GetHashCode ( ) ;
265+ hash = hash * 31 + obj . IsRequired . GetHashCode ( ) ;
266+ return hash ;
267+ }
268+ #endif
269+ }
270+ }
179271 }
180272}
0 commit comments