// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Runtime.CompilerServices;
using Internal.Runtime.CompilerServices;
using System.Runtime.InteropServices;
public static extern double Exchange(ref double location1, double value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern object Exchange(ref object location1, object value);
+ public static extern object? Exchange(ref object? location1, object? value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr Exchange(ref IntPtr location1, IntPtr value);
// This whole method reduces to a single call to Exchange(ref object, object) but
// the JIT thinks that it will generate more native code than it actually does.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static T Exchange<T>(ref T location1, T value) where T : class
+ public static T Exchange<T>(ref T location1, T value) where T : class?
{
- return Unsafe.As<T>(Exchange(ref Unsafe.As<T, object>(ref location1), value));
+ return Unsafe.As<T>(Exchange(ref Unsafe.As<T, object?>(ref location1), value));
}
/// <summary>
public static extern double CompareExchange(ref double location1, double value, double comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern object CompareExchange(ref object location1, object value, object comparand);
+ public static extern object? CompareExchange(ref object? location1, object? value, object? comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand);
// ret
// The workaround is no longer strictly necessary now that we have Unsafe.As but it does
// have the advantage of being less sensitive to JIT's inliner decisions.
- public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class
+ public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class?
{
- return Unsafe.As<T>(CompareExchange(ref Unsafe.As<T, object>(ref location1), value, comparand));
+ return Unsafe.As<T>(CompareExchange(ref Unsafe.As<T, object?>(ref location1), value, comparand));
}
// BCL-internal overload that returns success via a ref bool param, useful for reliable spin locks.
/// if an object was not used and to then dispose of the object appropriately.
/// </para>
/// </remarks>
- public static T EnsureInitialized<T>(ref T target) where T : class =>
+ public static T EnsureInitialized<T>(ref T target) where T : class? =>
Volatile.Read(ref target) ?? EnsureInitializedCore(ref target);
/// <summary>
/// <typeparam name="T">The reference type of the reference to be initialized.</typeparam>
/// <param name="target">The variable that need to be initialized</param>
/// <returns>The initialized variable</returns>
- private static T EnsureInitializedCore<T>(ref T target) where T : class
+ private static T EnsureInitializedCore<T>(ref T target) where T : class?
{
try
{
/// if an object was not used and to then dispose of the object appropriately.
/// </para>
/// </remarks>
- public static T EnsureInitialized<T>(ref T target, Func<T> valueFactory) where T : class =>
+ public static T EnsureInitialized<T>(ref T target, Func<T> valueFactory) where T : class? =>
Volatile.Read(ref target) ?? EnsureInitializedCore(ref target, valueFactory);
/// <summary>
/// <param name="target">The variable that need to be initialized</param>
/// <param name="valueFactory">The delegate that will be executed to initialize the target</param>
/// <returns>The initialized variable</returns>
- private static T EnsureInitializedCore<T>(ref T target, Func<T> valueFactory) where T : class
+ private static T EnsureInitializedCore<T>(ref T target, Func<T> valueFactory) where T : class?
{
T value = valueFactory();
if (value == null)
/// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param>
/// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the reference.</param>
/// <returns>The initialized value of type <typeparamref name="T"/>.</returns>
- public static T EnsureInitialized<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class =>
+ public static T EnsureInitialized<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class? =>
Volatile.Read(ref target) ?? EnsureInitializedCore(ref target, ref syncLock, valueFactory);
/// <summary>
/// The <see cref="T:System.Func{T}"/> to invoke in order to produce the lazily-initialized value.
/// </param>
/// <returns>The initialized object.</returns>
- private static T EnsureInitializedCore<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class
+ private static T EnsureInitializedCore<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class?
{
// Lazily initialize the lock if necessary and then double check if initialization is still required.
lock (EnsureLockInitialized(ref syncLock))
private static object EnsureLockInitialized(ref object? syncLock) =>
syncLock ??
Interlocked.CompareExchange(ref syncLock, new object(), null) ??
- syncLock;
+ syncLock!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Internal.Runtime.CompilerServices;
#endregion
#region T
- private struct VolatileObject { public volatile object Value; }
+ private struct VolatileObject { public volatile object? Value; }
[Intrinsic]
[NonVersionable]
- public static T Read<T>(ref T location) where T : class =>
+ public static T Read<T>(ref T location) where T : class? =>
Unsafe.As<T>(Unsafe.As<T, VolatileObject>(ref location).Value);
[Intrinsic]
[NonVersionable]
- public static void Write<T>(ref T location, T value) where T : class =>
+ public static void Write<T>(ref T location, T value) where T : class? =>
Unsafe.As<T, VolatileObject>(ref location).Value = value;
#endregion
}