| File: src\Shared\EmptyCollections\EmptyCollectionExtensions.cs | Web Access |
| Project: src\test\Generators\Microsoft.Gen.Logging\Unit\Microsoft.Gen.Logging.Unit.Tests.csproj (Microsoft.Gen.Logging.Unit.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; #pragma warning disable CA1716 namespace Microsoft.Shared.Collections; #pragma warning restore CA1716 /// <summary> /// Defines static methods used to optimize the use of empty collections. /// </summary> #if !SHARED_PROJECT [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] #endif internal static class EmptyCollectionExtensions { /// <summary> /// Returns an optimized empty collection if the input is <see langword="null"/> or empty, otherwise returns the input. /// </summary> /// <typeparam name="T">The type of the collection.</typeparam> /// <param name="collection">The collection to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty type if the input collection is <see langword="null"/> or empty, otherwise the collection.</returns> /// <remarks> /// Substituting a static collection whenever an empty collection is needed helps in two ways. First, /// it allows the original empty collection to be garbage collected, freeing memory. Second, the /// empty collection that is returned is optimized to not allocated memory whenever the collection is /// enumerated. /// </remarks> public static IReadOnlyCollection<T> EmptyIfNull<T>(this IReadOnlyCollection<T>? collection) => collection == null || collection.Count == 0 ? EmptyReadOnlyList<T>.Instance : collection; /// <summary> /// Returns an optimized empty collection if the input is <see langword="null"/> or empty, otherwise returns the input. /// </summary> /// <typeparam name="T">The type of the collection.</typeparam> /// <param name="collection">The collection to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty type if the input collection is <see langword="null"/> or empty, otherwise the collection.</returns> /// <remarks> /// Substituting a static collection whenever an empty collection is needed helps in two ways. First, /// it allows the original empty collection to be garbage collected, freeing memory. Second, the /// empty collection that is returned is optimized to not allocated memory whenever the collection is /// enumerated. /// </remarks> public static IEnumerable<T> EmptyIfNull<T>(this ICollection<T>? collection) => collection == null || collection.Count == 0 ? EmptyReadOnlyList<T>.Instance : collection; /// <summary> /// Returns an optimized empty collection if the input is <see langword="null"/> or empty, otherwise returns the input. /// </summary> /// <typeparam name="T">The type of the collection.</typeparam> /// <param name="list">The collection to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty type if the input collection is <see langword="null"/> or empty, otherwise the collection.</returns> /// <remarks> /// Substituting a static collection whenever an empty collection is needed helps in two ways. First, /// it allows the original empty collection to be garbage collected, freeing memory. Second, the /// empty collection that is returned is optimized to not allocated memory whenever the collection is /// enumerated. /// </remarks> public static IReadOnlyList<T> EmptyIfNull<T>(this IReadOnlyList<T>? list) => list == null || list.Count == 0 ? EmptyReadOnlyList<T>.Instance : list; /// <summary> /// Returns an optimized empty list if the input is <see langword="null"/> or empty, otherwise returns the input. /// </summary> /// <typeparam name="T">The type of the collection.</typeparam> /// <param name="list">The list to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty type if the input collection is <see langword="null"/> or empty, otherwise the collection.</returns> /// <remarks> /// Substituting a static list whenever an empty collection is needed helps in two ways. First, /// it allows the original empty collection to be garbage collected, freeing memory. Second, the /// empty collection that is returned is optimized to not allocated memory whenever the collection is /// enumerated. /// </remarks> public static IEnumerable<T> EmptyIfNull<T>(this IList<T>? list) => list == null || list.Count == 0 ? EmptyReadOnlyList<T>.Instance : list; /// <summary> /// Returns an optimized empty array if the input is <see langword="null"/> or empty, otherwise returns the input. /// </summary> /// <typeparam name="T">The type of the array.</typeparam> /// <param name="array">The array to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty array if the input array is <see langword="null"/> or empty, otherwise the array.</returns> public static T[] EmptyIfNull<T>(this T[]? array) => array == null || array.Length == 0 ? Array.Empty<T>() : array; /// <summary> /// Returns an optimized empty collection if the input is <see langword="null"/> or can be determined to be empty, otherwise returns the input. /// </summary> /// <typeparam name="T">The type of the collection.</typeparam> /// <param name="enumerable">The collection to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty type if the input collection is <see langword="null"/> or empty, otherwise the collection.</returns> /// <remarks> /// This method does not enumerate the collection. /// </remarks> public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T>? enumerable) { if (enumerable == null) { return EmptyReadOnlyList<T>.Instance; } // note this takes care of the IReadOnlyList<T> case too if (enumerable is IReadOnlyCollection<T> rc && rc.Count == 0) { return EmptyReadOnlyList<T>.Instance; } // note this takes care of the IList<T> case too if (enumerable is ICollection<T> c && c.Count == 0) { return EmptyReadOnlyList<T>.Instance; } return enumerable; } /// <summary> /// Returns an optimized empty dictionary if the input is <see langword="null"/> or can be determined to be empty, otherwise returns the input. /// </summary> /// <typeparam name="TKey">The key type of the dictionary.</typeparam> /// <typeparam name="TValue">The value type of the dictionary.</typeparam> /// <param name="dictionary">The dictionary to check for <see langword="null"/> or empty.</param> /// <returns>Returns a static instance of an empty type if the input dictionary is <see langword="null"/> or empty, otherwise the dictionary.</returns> /// <remarks> /// Note that this method does not enumerate the dictionary. /// </remarks> public static IReadOnlyDictionary<TKey, TValue> EmptyIfNull<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue>? dictionary) where TKey : notnull { if (dictionary == null || dictionary.Count == 0) { return EmptyReadOnlyDictionary<TKey, TValue>.Instance; } return dictionary; } }