internal ConverterCollection()
 {
     _cache = new ConcurrentDictionary <Type, ValueConverter>();
     _types = new Dictionary <Type, ConverterTypeCollection>();
     _mappedGenericTypes = new Dictionary <Type, GenericConverterTypeCollection>();
     _globalGenericTypes = new GenericConverterTypeCollection();
 }
        public void AddGenericConditional(Type openType, Type openConverterType, Func <TypeInfo, PropertyInfo, bool> condition, params Func <TypeInfo, Type>[] innerTypeSelectors)
        {
            if (openType.IsConstructedGenericType)
            {
                throw new InvalidOperationException($"{nameof(openType)} must be an open generic");
            }
            if (openConverterType.IsConstructedGenericType)
            {
                throw new InvalidOperationException($"{nameof(openConverterType)} must be an open generic");
            }
            if (innerTypeSelectors.Length != openConverterType.GetTypeInfo().GenericTypeParameters.Length)
            {
                throw new InvalidOperationException($"{nameof(innerTypeSelectors)} must be the same length as generic params in {nameof(openConverterType)}");
            }

            if (!_mappedGenericTypes.TryGetValue(openType, out var converters))
            {
                _mappedGenericTypes.Add(openType, converters = new GenericConverterTypeCollection());
            }
            converters.ConditionalConverters.Add(new GenericConditionalDefinition(new GenericDefinition(openConverterType, innerTypeSelectors), condition));
        }