Generic type parameters could not accept ref struct types like Span<T> or ReadOnlySpan<T>. This meant high-performance code using spans could not participate in generic abstractions such as IEnumerable<T> or IReadOnlyList<T>.
C# 13 introduces the allows ref struct anti-constraint, enabling generic type parameters to accept ref struct types while the compiler enforces the necessary lifetime restrictions.
Code
C#
static T Sum<T>(params ReadOnlySpan<T> values) where T : INumber<T>, allows ref struct
{
T result = T.Zero;
foreach (var value in values)
result += value;
return result;
}
// Works with Span<T> for zero-allocation scenarios
var total = Sum(1, 2, 3, 4, 5);C#
// Could not pass Span<T> to generic methods
// Had to write non-generic overloads or use arrays instead
static T Sum<T>(params T[] values) where T : INumber<T>
{
T result = T.Zero;
foreach (var value in values)
result += value;
return result;
}Notes
allows ref structis an anti-constraint that relaxes the default restriction rather than adding one- The compiler ensures
ref structvalues are not used in ways that would violate their lifetime rules (e.g. boxing, storing in fields of non-ref structtypes) - Enables the BCL to offer
Span<T>-based overloads in generic APIs