diff options
author | Stephen Toub <stoub@microsoft.com> | 2019-04-01 20:20:02 -0400 |
---|---|---|
committer | Dan Moseley <danmose@microsoft.com> | 2019-04-01 17:20:02 -0700 |
commit | e06e85d79882027ecb4315ffcab76a6eecee030c (patch) | |
tree | 7e5141b975643e074b5f6c575c100f1437f7f4a0 /src | |
parent | b86e0c59fc4b2691131de3cd789a4309e3cb7252 (diff) | |
download | coreclr-e06e85d79882027ecb4315ffcab76a6eecee030c.tar.gz coreclr-e06e85d79882027ecb4315ffcab76a6eecee030c.tar.bz2 coreclr-e06e85d79882027ecb4315ffcab76a6eecee030c.zip |
Nullable: Lazy (#23639)
Diffstat (limited to 'src')
3 files changed, 33 insertions, 30 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Lazy.cs b/src/System.Private.CoreLib/shared/System/Lazy.cs index ca445fc9d5..1fce87d0ca 100644 --- a/src/System.Private.CoreLib/shared/System/Lazy.cs +++ b/src/System.Private.CoreLib/shared/System/Lazy.cs @@ -10,9 +10,9 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Diagnostics; using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; using System.Threading; namespace System @@ -51,7 +51,7 @@ namespace System internal LazyState State { get; } - private readonly ExceptionDispatchInfo _exceptionDispatch; + private readonly ExceptionDispatchInfo? _exceptionDispatch; /// <summary> /// Constructor that defines the state @@ -121,14 +121,14 @@ namespace System } } - internal static LazyThreadSafetyMode? GetMode(LazyHelper state) + internal static LazyThreadSafetyMode? GetMode(LazyHelper? state) { if (state == null) return null; // we don't know the mode anymore return state.GetMode(); } - internal static bool GetIsValueFaulted(LazyHelper state) => state?._exceptionDispatch != null; + internal static bool GetIsValueFaulted(LazyHelper? state) => state?._exceptionDispatch != null; internal static LazyHelper Create(LazyThreadSafetyMode mode, bool useDefaultConstructor) { @@ -189,14 +189,14 @@ namespace System } // _state, a volatile reference, is set to null after _value has been set - private volatile LazyHelper _state; + private volatile LazyHelper? _state; // we ensure that _factory when finished is set to null to allow garbage collector to clean up // any referenced items - private Func<T> _factory; + private Func<T>? _factory; // _value eventually stores the lazily created value. It is valid when _state = null. - private T _value; + private T _value = default!; // TODO-NULLABLE: Generic annotation /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that @@ -206,7 +206,7 @@ namespace System /// An instance created with this constructor may be used concurrently from multiple threads. /// </remarks> public Lazy() - : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:true) + : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor: true) { } @@ -237,7 +237,7 @@ namespace System /// An instance created with this constructor may be used concurrently from multiple threads. /// </remarks> public Lazy(Func<T> valueFactory) - : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:false) + : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor: false) { } @@ -248,7 +248,7 @@ namespace System /// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time. /// </param> public Lazy(bool isThreadSafe) : - this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:true) + this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor: true) { } @@ -275,7 +275,7 @@ namespace System /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is /// a null reference (Nothing in Visual Basic).</exception> public Lazy(Func<T> valueFactory, bool isThreadSafe) : - this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:false) + this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor: false) { } @@ -295,7 +295,7 @@ namespace System { } - private Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor) + private Lazy(Func<T>? valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor) { if (valueFactory == null && !useDefaultConstructor) throw new ArgumentNullException(nameof(valueFactory)); @@ -314,7 +314,7 @@ namespace System { try { - Func<T> factory = _factory; + Func<T>? factory = _factory; if (factory == null) throw new InvalidOperationException(SR.Lazy_Value_RecursiveCallsToValue); _factory = null; @@ -351,7 +351,7 @@ namespace System private void PublicationOnly(LazyHelper publicationOnly, T possibleValue) { - LazyHelper previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly); + LazyHelper? previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly); if (previous == publicationOnly) { _factory = null; @@ -367,7 +367,7 @@ namespace System private void PublicationOnlyViaFactory(LazyHelper initializer) { - Func<T> factory = _factory; + Func<T>? factory = _factory; if (factory == null) { PublicationOnlyWaitForOtherThreadToPublish(); @@ -393,7 +393,7 @@ namespace System { // we have to create a copy of state here, and use the copy exclusively from here on in // so as to ensure thread safety. - var state = _state; + LazyHelper? state = _state; if (state != null) { switch (state.State) @@ -440,9 +440,11 @@ namespace System /// <exception cref="T:System.NullReferenceException"> /// The <see cref="Value"/> is null. /// </exception> - public override string ToString() + public override string? ToString() { - return IsValueCreated ? Value.ToString() : SR.Lazy_ToString_ValueNotCreated; + return IsValueCreated ? + Value!.ToString() : // TODO-NULLABLE: Documented to throw NullReferenceException + SR.Lazy_ToString_ValueNotCreated; } /// <summary>Gets the value of the Lazy<T> for debugging display purposes.</summary> @@ -452,7 +454,7 @@ namespace System { if (!IsValueCreated) { - return default; + return default!; // TODO-NULLABLE: generic nullability } return _value; } @@ -527,8 +529,7 @@ namespace System /// <summary>Returns the value of the Lazy object.</summary> public T Value { - get - { return _lazy.ValueForDebugDisplay; } + get { return _lazy.ValueForDebugDisplay; } } /// <summary>Returns the execution mode of the Lazy object</summary> diff --git a/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs b/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs index e7928b6f93..ef03b7e97c 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs @@ -8,6 +8,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Diagnostics; namespace System.Threading @@ -60,7 +61,7 @@ namespace System.Threading { try { - Interlocked.CompareExchange(ref target, Activator.CreateInstance<T>(), null); + Interlocked.CompareExchange(ref target, Activator.CreateInstance<T>(), null!); // TODO-NULLABLE: Need to be able to express ref T nullability } catch (MissingMethodException) { @@ -117,7 +118,7 @@ namespace System.Threading throw new InvalidOperationException(SR.Lazy_StaticInit_InvalidOperation); } - Interlocked.CompareExchange(ref target, value, null); + Interlocked.CompareExchange(ref target, value, null!); // TODO-NULLABLE: Need to be able to express ref T nullability Debug.Assert(target != null); return target; } @@ -134,7 +135,7 @@ namespace System.Threading /// <param name="syncLock">A reference to an object used as the mutually exclusive lock for initializing /// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param> /// <returns>The initialized value of type <typeparamref name="T"/>.</returns> - public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock) + public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object? syncLock) { // Fast path. if (Volatile.Read(ref initialized)) @@ -156,7 +157,7 @@ namespace System.Threading /// a new object will be instantiated. /// </param> /// <returns>The initialized object.</returns> - private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock) + private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object? syncLock) { // Lazily initialize the lock if necessary and then double check if initialization is still required. lock (EnsureLockInitialized(ref syncLock)) @@ -193,7 +194,7 @@ namespace System.Threading /// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the /// reference or value.</param> /// <returns>The initialized value of type <typeparamref name="T"/>.</returns> - public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory) + public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object? syncLock, Func<T> valueFactory) { // Fast path. if (Volatile.Read(ref initialized)) @@ -217,7 +218,7 @@ namespace System.Threading /// 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 bool initialized, ref object syncLock, Func<T> valueFactory) + private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object? syncLock, Func<T> valueFactory) { // Lazily initialize the lock if necessary and then double check if initialization is still required. lock (EnsureLockInitialized(ref syncLock)) @@ -241,7 +242,7 @@ namespace System.Threading /// <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> @@ -256,7 +257,7 @@ namespace System.Threading /// 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)) @@ -280,7 +281,7 @@ namespace System.Threading /// <param name="syncLock">A reference to a location containing a mutual exclusive lock. If <paramref name="syncLock"/> is null, /// a new object will be instantiated.</param> /// <returns>Initialized lock object.</returns> - private static object EnsureLockInitialized(ref object syncLock) => + private static object EnsureLockInitialized(ref object? syncLock) => syncLock ?? Interlocked.CompareExchange(ref syncLock, new object(), null) ?? syncLock; diff --git a/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs b/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs index 2d13f23762..ae650824d7 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs @@ -8,6 +8,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable namespace System.Threading { /// <summary> |