Skip to content

Commit ebf4cef

Browse files
committed
Refactored the nullable extension
1 parent e6968bb commit ebf4cef

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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

Microsoft.Toolkit.HighPerformance/Helpers/NullableHelper.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)