1
0
mirror of https://github.com/chylex/.NET-Community-Toolkit.git synced 2025-09-23 00:24:47 +02:00
Files
.github
CommunityToolkit.Common
CommunityToolkit.Diagnostics
CommunityToolkit.HighPerformance
Attributes
Buffers
Enumerables
Extensions
ArrayExtensions.1D.cs
ArrayExtensions.2D.cs
ArrayExtensions.3D.cs
ArrayPoolBufferWriterExtensions.cs
ArrayPoolExtensions.cs
BoolExtensions.cs
HashCodeExtensions.cs
IBufferWriterExtensions.cs
IMemoryOwnerExtensions.cs
ListExtensions.cs
MemoryExtensions.cs
NullableExtensions.cs
ReadOnlyMemoryExtensions.cs
ReadOnlySpanExtensions.cs
SpanExtensions.cs
SpinLockExtensions.cs
StreamExtensions.cs
StringExtensions.cs
Helpers
Memory
Properties
Streams
Box{T}.cs
CommunityToolkit.HighPerformance.csproj
NullableReadOnlyRef{T}.cs
NullableRef{T}.cs
ReadOnlyRef{T}.cs
Ref{T}.cs
CommunityToolkit.Mvvm
CommunityToolkit.Mvvm.SourceGenerators
build
tests
.editorconfig
.git-blame-ignore-revs
.gitattributes
.gitignore
.runsettings
CODE_OF_CONDUCT.md
Contributing.md
Directory.Build.props
Directory.Build.targets
License.md
README.md
ThirdPartyNotices.txt
azure-pipelines.yml
dotnet Community Toolkit.sln
toolkit.snk
version.json
.NET-Community-Toolkit/CommunityToolkit.HighPerformance/Extensions/NullableExtensions.cs
2021-12-17 13:58:11 +01:00

75 lines
3.4 KiB
C#

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This extension is restricted to the .NET 6 because it shares the same BCL
// across all targets, ensuring that the layout of our Nullable<T> mapping type
// will be correct. Exposing this API on older targets (especially .NET Standard)
// is not guaranteed to be correct and could result in invalid memory accesses.
#if NET6_0_OR_GREATER
using System;
using System.Runtime.CompilerServices;
namespace CommunityToolkit.HighPerformance;
/// <summary>
/// Helpers for working with the <see cref="Nullable{T}"/> type.
/// </summary>
public static class NullableExtensions
{
/// <summary>
/// Returns a reference to the value of the input <see cref="Nullable{T}"/> instance, regardless of whether
/// the <see cref="Nullable{T}.HasValue"/> property is returning <see langword="true"/> or not. If that is not
/// the case, this method will still return a reference to the underlying <see langword="default"/> value.
/// </summary>
/// <typeparam name="T">The type of the underlying value.</typeparam>
/// <param name="value">The <see cref="Nullable{T}"/>.</param>
/// <returns>A reference to the underlying value from the input <see cref="Nullable{T}"/> instance.</returns>
/// <remarks>
/// Note that attempting to mutate the returned reference will not change the value returned by <see cref="Nullable{T}.HasValue"/>.
/// That means that reassigning the value of an empty instance will not make <see cref="Nullable{T}.HasValue"/> return <see langword="true"/>.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T DangerousGetValueOrDefaultReference<T>(this ref T? value)
where T : struct
{
return ref Unsafe.As<T?, RawNullableData<T>>(ref value).Value;
}
/// <summary>
/// Returns a reference to the value of the input <see cref="Nullable{T}"/> instance, or a <see langword="null"/> <typeparamref name="T"/> reference.
/// </summary>
/// <typeparam name="T">The type of the underlying value.</typeparam>
/// <param name="value">The <see cref="Nullable{T}"/>.</param>
/// <returns>A reference to the value of the input <see cref="Nullable{T}"/> instance, or a <see langword="null"/> <typeparamref name="T"/> reference.</returns>
/// <remarks>The returned reference can be tested for <see langword="null"/> using <see cref="Unsafe.IsNullRef{T}(ref T)"/>.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe ref T DangerousGetValueOrNullReference<T>(ref this T? value)
where T : struct
{
if (value.HasValue)
{
return ref Unsafe.As<T?, RawNullableData<T>>(ref value).Value;
}
return ref Unsafe.NullRef<T>();
}
/// <summary>
/// Mapping type that reflects the internal layout of the <see cref="Nullable{T}"/> type.
/// See https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Nullable.cs.
/// </summary>
/// <typeparam name="T">The value type wrapped by the current instance.</typeparam>
private struct RawNullableData<T>
where T : struct
{
#pragma warning disable CS0649 // Unassigned fields
public bool HasValue;
public T Value;
#pragma warning restore CS0649
}
}
#endif