| | | 1 | | // Copyright (c) ZeroC, Inc. |
| | | 2 | | |
| | | 3 | | using System.Collections; |
| | | 4 | | |
| | | 5 | | namespace IceRpc.Features; |
| | | 6 | | |
| | | 7 | | /// <summary>Default implementation of <see cref="IFeatureCollection" />.</summary> |
| | | 8 | | public class FeatureCollection : IFeatureCollection |
| | | 9 | | { |
| | | 10 | | /// <summary>Gets a shared empty read-only instance.</summary> |
| | | 11 | | /// <value>An empty <see cref="FeatureCollection" />.</value> |
| | 11736 | 12 | | public static IFeatureCollection Empty { get; } = new FeatureCollection().AsReadOnly(); |
| | | 13 | | |
| | | 14 | | /// <summary>Gets a value indicating whether this feature collection is read-only or read-write.</summary> |
| | | 15 | | /// <value>Always <see langword="false" /> with this class.</value> |
| | 150 | 16 | | public bool IsReadOnly => false; |
| | | 17 | | |
| | | 18 | | private readonly IFeatureCollection? _defaults; |
| | 228 | 19 | | private readonly Dictionary<Type, object> _features = new(); |
| | | 20 | | |
| | | 21 | | /// <inheritdoc/> |
| | | 22 | | public object? this[Type key] |
| | | 23 | | { |
| | 909 | 24 | | get => _features.TryGetValue(key, out object? value) ? value : _defaults?[key]; |
| | | 25 | | |
| | | 26 | | set |
| | 322 | 27 | | { |
| | 322 | 28 | | if (value is null) |
| | 3 | 29 | | { |
| | 3 | 30 | | _ = _features.Remove(key); |
| | 3 | 31 | | } |
| | | 32 | | else |
| | 319 | 33 | | { |
| | 319 | 34 | | _features[key] = value; |
| | 319 | 35 | | } |
| | 322 | 36 | | } |
| | | 37 | | } |
| | | 38 | | |
| | | 39 | | /// <summary>Constructs an empty read-write feature collection.</summary> |
| | 43 | 40 | | public FeatureCollection() |
| | 43 | 41 | | { |
| | 43 | 42 | | } |
| | | 43 | | |
| | | 44 | | /// <summary>Constructs an empty read-write feature collection with defaults.</summary> |
| | | 45 | | /// <param name="defaults">The feature collection that provide default values.</param> |
| | 185 | 46 | | public FeatureCollection(IFeatureCollection defaults) => |
| | | 47 | | // no need to query the empty read-only collection for defaults; any other feature collection (even empty and |
| | | 48 | | // read-only) can change over time |
| | 185 | 49 | | _defaults = defaults == Empty ? null : defaults; |
| | | 50 | | |
| | | 51 | | /// <inheritdoc/> |
| | 905 | 52 | | public TFeature? Get<TFeature>() => this[typeof(TFeature)] is object value ? (TFeature)value : default; |
| | | 53 | | |
| | | 54 | | /// <inheritdoc /> |
| | 0 | 55 | | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
| | | 56 | | |
| | | 57 | | /// <summary>Returns an enumerator that iterates over this feature collection.</summary> |
| | | 58 | | /// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through this feature collection. |
| | | 59 | | /// </returns> |
| | | 60 | | public IEnumerator<KeyValuePair<Type, object>> GetEnumerator() |
| | 10 | 61 | | { |
| | 50 | 62 | | foreach (KeyValuePair<Type, object> pair in _features) |
| | 10 | 63 | | { |
| | 10 | 64 | | yield return pair; |
| | 10 | 65 | | } |
| | | 66 | | |
| | 10 | 67 | | if (_defaults is not null) |
| | 6 | 68 | | { |
| | 42 | 69 | | foreach (KeyValuePair<Type, object> pair in _defaults) |
| | 12 | 70 | | { |
| | 12 | 71 | | if (!_features.ContainsKey(pair.Key)) |
| | 8 | 72 | | { |
| | 8 | 73 | | yield return pair; |
| | 8 | 74 | | } |
| | 12 | 75 | | } |
| | 6 | 76 | | } |
| | 10 | 77 | | } |
| | | 78 | | |
| | | 79 | | /// <inheritdoc/> |
| | 310 | 80 | | public void Set<TFeature>(TFeature? feature) => this[typeof(TFeature)] = feature; |
| | | 81 | | } |