diff --git a/src/Lumina/Extensions/LinqExtensions.cs b/src/Lumina/Extensions/LinqExtensions.cs
new file mode 100644
index 00000000..087e344c
--- /dev/null
+++ b/src/Lumina/Extensions/LinqExtensions.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lumina.Extensions;
+
+///
+/// Utility class for additional struct-based enumerable operations.
+///
+/// Most useful for easily looping over and types.
+public static class LinqExtensions
+{
+ /// Returns the first element of a sequence, or if the sequence contains no elements.
+ /// The type of the elements of .
+ /// The to return the first element of.
+ /// if is empty; otherwise, the first element in .
+ /// is .
+ public static T? FirstOrNull( this IEnumerable source ) where T : struct
+ {
+ ArgumentNullException.ThrowIfNull( source );
+
+ var e = source.GetEnumerator();
+ if( e.MoveNext() )
+ {
+ return e.Current;
+ }
+
+ return null;
+ }
+
+ /// Returns the first element of the sequence that satisfies a condition or if no such element is found.
+ /// The type of the elements of .
+ /// An to return an element from.
+ /// A function to test each element for a condition.
+ /// if is empty or if no element passes the test specified by ; otherwise, the first element in that passes the test specified by .
+ /// or is .
+ public static T? FirstOrNull( this IEnumerable source, Predicate predicate ) where T : struct
+ {
+ ArgumentNullException.ThrowIfNull( source );
+ ArgumentNullException.ThrowIfNull( predicate );
+
+ foreach( var element in source )
+ {
+ if( predicate( element ) )
+ {
+ return element;
+ }
+ }
+
+ return null;
+ }
+
+ // https://github.com/dotnet/runtime/blob/96ae7cfefb0ae0ad621edc56bf690da174d9c7ab/src/libraries/System.Linq/src/System/Linq/First.cs#L65
+ /// Attempts to get the first element of a sequence.
+ /// The type of the elements of .
+ /// The to return the first element of.
+ /// if is empty; otherwise, the first element in .
+ /// Whether or not the first element was found.
+ /// is .
+ public static bool TryGetFirst( this IEnumerable source, out T result ) where T : struct
+ {
+ ArgumentNullException.ThrowIfNull( source );
+
+ using( var e = source.GetEnumerator() )
+ {
+ if( e.MoveNext() )
+ {
+ result = e.Current;
+ return true;
+ }
+ }
+
+ result = default;
+ return false;
+ }
+
+ // https://github.com/dotnet/runtime/blob/96ae7cfefb0ae0ad621edc56bf690da174d9c7ab/src/libraries/System.Linq/src/System/Linq/First.cs#L105
+ /// Attempts to get the first element of the sequence that satisfies a condition.
+ /// The type of the elements of .
+ /// An to return an element from.
+ /// A function to test each element for a condition.
+ /// if is empty or if no element passes the test specified by ; otherwise, the first element in that passes the test specified by .
+ /// Whether or not an element was found that passes .
+ /// or is .
+ public static bool TryGetFirst( this IEnumerable source, Predicate predicate, out T result ) where T : struct
+ {
+ ArgumentNullException.ThrowIfNull( source );
+ ArgumentNullException.ThrowIfNull( predicate );
+
+ foreach( var element in source )
+ {
+ if( predicate( element ) )
+ {
+ result = element;
+ return true;
+ }
+ }
+
+ result = default;
+ return false;
+ }
+}
\ No newline at end of file