diff --git a/C#-and-.NET-docs-supplement.md b/C#-and-.NET-docs-supplement.md index 9e815f2..4b3abaf 100644 --- a/C#-and-.NET-docs-supplement.md +++ b/C#-and-.NET-docs-supplement.md @@ -66,7 +66,53 @@ You can only have 1 `default:` branch (not to be confused with `case default:`), ## `MemoryMarshal.Cast` can't be used with reference types -See [this SO answer](https://stackoverflow.com/a/79146967/7467292). tl;dr: It's possible in .NET Core only. +See [this SO answer](https://stackoverflow.com/a/79146967). tl;dr: It's possible in .NET Core only. + +
+full implementations of extension methods for later + +```csharp +public static Span Cast(Span span) + where TTo: class + where TFrom: class +{ + if (typeof(TTo).IsAssignableFrom(typeof(TFrom))) throw new InvalidCastException(); + return UnsafeDowncast(span); +} + +public static ReadOnlySpan Cast(ReadOnlySpan span) + where TTo: class + where TFrom: class +{ + if (typeof(TTo).IsAssignableFrom(typeof(TFrom))) throw new InvalidCastException(); + return UnsafeDowncast(span); +} + +public static Span CastUp(Span span) + where TBase: class + where TDerived: class, TBase + => UnsafeDowncast(span); + +public static ReadOnlySpan CastUp(ReadOnlySpan span) + where TBase: class + where TDerived: class, TBase + => UnsafeDowncast(span); + +public static Span UnsafeDowncast(Span span) + where TTo: class + where TFrom: class + => MemoryMarshal.CreateSpan( + ref Unsafe.As(ref MemoryMarshal.GetReference(span)), + span.Length); + +public static ReadOnlySpan UnsafeDowncast(ReadOnlySpan span) + where TTo: class + where TFrom: class + => MemoryMarshal.CreateReadOnlySpan( + ref Unsafe.As(ref MemoryMarshal.GetReference(span)), + span.Length); +``` +
## MSBuild `Condition` placement