< Summary

Information
Class: MoreStructures.Utilities.ValueReadOnlyDictionary<T1, T2>
Assembly: MoreStructures
File(s): /home/runner/work/MoreStructures/MoreStructures/MoreStructures/Utilities/ValueReadOnlyDictionary.cs
Line coverage
100%
Covered lines: 14
Uncovered lines: 0
Coverable lines: 14
Total lines: 95
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
.ctor(...)100%1100%
Equals(...)100%6100%
GetHashCode()100%4100%
ToString()100%2100%
op_Equality(...)100%1100%
op_Inequality(...)100%1100%

File(s)

/home/runner/work/MoreStructures/MoreStructures/MoreStructures/Utilities/ValueReadOnlyDictionary.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2
 3namespace MoreStructures.Utilities;
 4
 5/// <summary>
 6/// A readonly immutable generic dictionary of non-null keys and values which performs equality by value.
 7/// </summary>
 8/// <typeparam name="TKey">The type of keys in the dictionary.</typeparam>
 9/// <typeparam name="TValue">The type of values in the dictionary.</typeparam>
 10/// <remarks>
 11/// Immutability can be guaranteed by cloning the provided dictionary and exposing a readonly view of it, but only
 12/// if immutability of underlying <typeparamref name="TKey"/> and <typeparamref name="TValue"/> is provided, for
 13/// example, by using immutable records.
 14/// </remarks>
 15public class ValueReadOnlyDictionary<TKey, TValue> : ReadOnlyDictionary<TKey, TValue>
 16    where TKey : notnull
 17    where TValue : notnull
 18{
 19    /// <summary>
 20    /// Creates value readonly dictionary out of the provided dictionary, and independent from it.
 21    /// </summary>
 22    /// <param name="dictionary">The dictionary to be used to build the readonly dictionary.</param>
 23    public ValueReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
 12505724        : base(new Dictionary<TKey, TValue>(dictionary))
 12505725    {
 12505726    }
 27
 28    /// <summary>
 29    /// Creates value readonly dictionary out of the provided entries, and independent from the provided
 30    /// enumerable of them.
 31    /// </summary>
 32    /// <param name="entries">The enumerable of entries to be used to build the readonly dictionary.</param>
 33
 34    public ValueReadOnlyDictionary(IEnumerable<KeyValuePair<TKey, TValue>> entries)
 335        : base(new Dictionary<TKey, TValue>(entries))
 336    {
 337    }
 38
 39    /// <inheritdoc path="//*[not(self::summary or self::remarks)]"/>
 40    /// <summary>
 41    ///     <inheritdoc/>
 42    ///     <br/>
 43    ///     Equality is calculated by value, i.e. on the dictionary key-value pairs directly.
 44    /// </summary>
 45    /// <remarks>
 46    /// Two dictionaries are considered equal by value if:
 47    /// <br/>
 48    /// - they have the same set of keys
 49    ///   <br/>
 50    /// - and the value associated, with each of the key by the two dictionaries are equal with each other.
 51    /// </remarks>
 52    public override bool Equals(object? obj) =>
 106453        obj is ValueReadOnlyDictionary<TKey, TValue> other &&
 106454        Count == other.Count &&
 106455        Keys.ToHashSet().SetEquals(other.Keys.ToHashSet()) &&
 192256        Keys.All(k => Equals(this[k], other[k]));
 57
 58    /// <inheritdoc path="//*[not(self::summary)]"/>
 59    /// <summary>
 60    ///     <inheritdoc/>
 61    ///     <br/>
 62    ///     The hash code is calculated by value, as an aggregate of the hash codes of its key value pairs.
 63    /// </summary>
 64    public override int GetHashCode() =>
 448665        this.Select(kvp => kvp.GetHashCode()).Aggregate(0.GetHashCode(), (acc, v) => acc ^ v);
 66
 67    /// <inheritdoc path="//*[not(self::summary)]"/>
 68    /// <summary>
 69    ///     <inheritdoc/>
 70    ///     <br/>
 71    ///     Format: "{[k1] = v1, [k2] = v2, ...}".
 72    /// </summary>
 73    public override string ToString() =>
 374        $"{{{string.Join(", ", this.Select(kvp => $"[{kvp.Key}] = {kvp.Value}"))}}}";
 75
 76    /// <summary>
 77    /// Compare the two provided value read-only dictionaries for equality by value.
 78    /// </summary>
 79    /// <param name="left">The first term of comparison.</param>
 80    /// <param name="right">The second term of comparison.</param>
 81    /// <returns>True if the two dictionaries are equal by their items, false otherwise.</returns>
 82    public static bool operator ==(
 83        ValueReadOnlyDictionary<TKey, TValue> left, ValueReadOnlyDictionary<TKey, TValue> right) =>
 384        Equals(left, right);
 85
 86    /// <summary>
 87    /// Compare the two provided value read-only dictionaries for inequality by value.
 88    /// </summary>
 89    /// <param name="left">The first term of comparison.</param>
 90    /// <param name="right">The second term of comparison.</param>
 91    /// <returns>True if the two dictionaries are different by their items, false otherwise.</returns>
 92    public static bool operator !=(
 93        ValueReadOnlyDictionary<TKey, TValue> left, ValueReadOnlyDictionary<TKey, TValue> right) =>
 394        !Equals(left, right);
 95}