public bool TryGet <TArguments, T>(TArguments arguments, ContextPredicate <TArguments, T> predicate, out T value)
        {
            if (typeof(TArguments).IsClass && EqualityComparer <TArguments> .Default.Equals(arguments, default))
            {
                throw new ArgumentNullException(nameof(arguments));
            }
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            return(OnTryGet(arguments, predicate, out value));
        }
        protected override bool OnTryGet <TArguments>(TArguments arguments, ContextPredicate <TArguments, object> predicate, out object value)
        {
            foreach (KeyValuePair <Type, List <object> > pair in m_values)
            {
                for (int i = 0; i < pair.Value.Count; i++)
                {
                    value = pair.Value[i];

                    if (predicate(arguments, value))
                    {
                        return(true);
                    }
                }
            }

            value = default;
            return(false);
        }
        protected override bool OnTryGet <TArguments, T>(TArguments arguments, ContextPredicate <TArguments, T> predicate, out T value)
        {
            Type type = typeof(T);

            if (m_values.TryGetValue(type, out List <object> values))
            {
                for (int i = 0; i < values.Count; i++)
                {
                    value = (T)values[i];

                    if (predicate(arguments, value))
                    {
                        return(true);
                    }
                }
            }

            foreach (KeyValuePair <Type, List <object> > pair in m_values)
            {
                if (type.IsAssignableFrom(pair.Key))
                {
                    for (int i = 0; i < pair.Value.Count; i++)
                    {
                        value = (T)pair.Value[i];

                        if (predicate(arguments, value))
                        {
                            return(true);
                        }
                    }
                }
            }

            value = default;
            return(false);
        }
 public object Get <TArguments>(TArguments arguments, ContextPredicate <TArguments, object> predicate)
 {
     return(TryGet(arguments, predicate, out object value) ? value : throw new ContextValueNotFoundByArgumentsException(arguments));
 }
 protected abstract bool OnTryGet <TArguments>(TArguments arguments, ContextPredicate <TArguments, object> predicate, out object value);
 protected abstract bool OnTryGet <TArguments, T>(TArguments arguments, ContextPredicate <TArguments, T> predicate, out T value);