public override bool CanConvert(Type typeToConvert)
        {
            if (typeToConvert.IsPrimitive)
            {
                return(false);
            }

            var nullableUnderlyingType = Nullable.GetUnderlyingType(typeToConvert);

            if (nullableUnderlyingType != null && nullableUnderlyingType.IsPrimitive)
            {
                return(false);
            }

            bool result;
            var  constructors = typeToConvert.GetConstructors(BindingFlags.Public | BindingFlags.Instance);

            if (constructors.Length != 1)
            {
                result = false;
            }
            else
            {
                var constructor   = constructors[0];
                var parameters    = constructor.GetParameters();
                var hasParameters = parameters.Length > 0;
                if (hasParameters)
                {
                    var properties = typeToConvert.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    result = true;
                    foreach (var parameter in parameters)
                    {
                        var hasMatchingProperty = properties.Any(p =>
                                                                 NameOfPropertyAndParameter.Matches(p.Name, parameter.Name, typeToConvert.IsAnonymous()));
                        if (!hasMatchingProperty)
                        {
                            result = false;
                            break;
                        }
                    }
                }
                else
                {
                    result = false;
                }
            }

            return(result);
        }
        public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var valueOfProperty        = new Dictionary <PropertyInfo, object>();
            var namedPropertiesMapping = GetNamedProperties(options, GetProperties(typeToConvert));

            reader.Read();
            while (true)
            {
                if (reader.TokenType != JsonTokenType.PropertyName && reader.TokenType != JsonTokenType.String)
                {
                    break;
                }

                string jsonPropName       = reader.GetString();
                string normalizedPropName = ConvertAndNormalizeName(jsonPropName, options);
                if (!namedPropertiesMapping.TryGetValue(normalizedPropName, out var obProp))
                {
                    reader.Read();
                }
                else
                {
                    var value = JsonSerializer.Deserialize(ref reader, obProp.PropertyType, options);
                    reader.Read();
                    valueOfProperty[obProp] = value;
                }
            }

            var ctor            = typeToConvert.GetConstructors(BindingFlags.Public | BindingFlags.Instance).First();
            var parameters      = ctor.GetParameters();
            var parameterValues = new object[parameters.Length];

            for (int index = 0; index < parameters.Length; index++)
            {
                var parameterInfo = parameters[index];
                var value         = valueOfProperty.First(prop =>
                                                          NameOfPropertyAndParameter.Matches(prop.Key.Name, parameterInfo.Name, typeToConvert.IsAnonymous())).Value;

                parameterValues[index] = value;
            }

            var instance = ctor.Invoke(parameterValues);

            return(instance);
        }