scratch-link/scratch-link-common/Extensions/ContainerExtensions.cs
2023-03-01 15:39:25 -08:00

51 lines
2.2 KiB
C#

// <copyright file="ContainerExtensions.cs" company="Scratch Foundation">
// Copyright (c) Scratch Foundation. All rights reserved.
// </copyright>
namespace ScratchLink.Extensions;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Extensions for use with containers or other enumerables.
/// </summary>
internal static class ContainerExtensions
{
/// <summary>
/// If this enumerable is null, return an empty enumerable of the same type.
/// Otherwise, return the enumerable as-is.
/// </summary>
/// <typeparam name="T">The type of object enumerated by the enumerable.</typeparam>
/// <param name="original">The possibly-null enumerable.</param>
/// <returns>A never-null enumerable.</returns>
public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> original) =>
original ?? Enumerable.Empty<T>();
/// <summary>
/// Attempt to retrieve a value and, if that succeeds, cast it. Good for dictionaries containing <c>object</c>.
/// If the key is not found, the output variable is set to the type's default value.
/// Adapted from <a href="https://stackoverflow.com/a/63203652">this Stack Overflow answer</a>.
/// </summary>
/// <typeparam name="TValueAs">The type to cast the value to.</typeparam>
/// <typeparam name="TKey">The type of key in the dictionary.</typeparam>
/// <typeparam name="TValue">The type of value in the dictionary.</typeparam>
/// <param name="dictionary">The dictionary to look in.</param>
/// <param name="key">The dictionary to look for.</param>
/// <param name="value">The variable to receive the casted value. Set to <c>default</c> if the key is not found.</param>
/// <returns>
/// True if the key was found, regardless of what happens in the cast, or false if the key was not found.
/// </returns>
public static bool TryGetValueAs<TValueAs, TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key, out TValueAs value)
where TValueAs : TValue
{
if (dictionary.TryGetValue(key, out TValue rawValue))
{
value = (TValueAs)rawValue;
return true;
}
value = default;
return false;
}
}