1
+ // Licensed to the .NET Foundation under one or more agreements.
2
+ // The .NET Foundation licenses this file to you under the MIT license.
3
+ // See the LICENSE file in the project root for more information.
4
+
5
+ // This extension is restricted to the .NET 5 because it shares the same BCL
6
+ // across all targets, ensuring that the layout of our Nullable<T> mapping type
7
+ // will be correct. Exposing this API on older targets (especially .NET Standard)
8
+ // is not guaranteed to be correct and could result in invalid memory accesses.
9
+ #if NET5_0
10
+
11
+ using System ;
12
+ using System . Runtime . CompilerServices ;
13
+
14
+ namespace Microsoft . Toolkit . HighPerformance . Extensions
15
+ {
16
+ /// <summary>
17
+ /// Helpers for working with the <see cref="Nullable{T}"/> type.
18
+ /// </summary>
19
+ public static class NullableExtensions
20
+ {
21
+ /// <summary>
22
+ /// Returns a reference to the value of the input <see cref="Nullable{T}"/> instance, regardless of whether
23
+ /// the <see cref="Nullable{T}.HasValue"/> property is returning <see langword="true"/> or not. If that is not
24
+ /// the case, this method will still return a reference to the underlying <see langword="default"/> value.
25
+ /// </summary>
26
+ /// <typeparam name="T">The type of the underlying value</typeparam>
27
+ /// <param name="value">The <see cref="Nullable{T}"/></param>
28
+ /// <returns>A reference to the underlying value from the input <see cref="Nullable{T}"/> instance.</returns>
29
+ /// <remarks>
30
+ /// Note that attempting to mutate the returned reference will not change the value returned by <see cref="Nullable{T}.HasValue"/>.
31
+ /// That means that reassigning the value of an empty instance will not make <see cref="Nullable{T}.HasValue"/> return <see langword="true"/>.
32
+ /// </remarks>
33
+ public static ref T DangerousGetValueOrDefaultReference < T > ( this ref T ? value )
34
+ where T : struct
35
+ {
36
+ return ref Unsafe . As < T ? , RawNullableData < T > > ( ref value ) . Value ;
37
+ }
38
+
39
+ /// <summary>
40
+ /// Mapping type that reflects the internal layout of the <see cref="Nullable{T}"/> type.
41
+ /// See https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Nullable.cs.
42
+ /// </summary>
43
+ /// <typeparam name="T">The value type wrapped by the current instance.</typeparam>
44
+ private struct RawNullableData < T >
45
+ where T : struct
46
+ {
47
+ #pragma warning disable CS0649 // Unassigned fields
48
+ public bool HasValue ;
49
+ public T Value ;
50
+ #pragma warning restore CS0649
51
+ }
52
+ }
53
+ }
54
+
55
+ #endif
0 commit comments