private static ConvertResult TryConvertInternal()

in src/Elastic.Apm/Libraries/Newtonsoft.Json/Utilities/ConvertUtils.cs [403:552]


		private static ConvertResult TryConvertInternal(object? initialValue, CultureInfo culture, Type targetType, out object? value)
		{
			if (initialValue == null) throw new ArgumentNullException(nameof(initialValue));

			if (ReflectionUtils.IsNullableType(targetType)) targetType = Nullable.GetUnderlyingType(targetType);

			var initialType = initialValue.GetType();

			if (targetType == initialType)
			{
				value = initialValue;
				return ConvertResult.Success;
			}

			// use Convert.ChangeType if both types are IConvertible
			if (IsConvertible(initialValue.GetType()) && IsConvertible(targetType))
			{
				if (targetType.IsEnum())
				{
					if (initialValue is string)
					{
						value = Enum.Parse(targetType, initialValue.ToString(), true);
						return ConvertResult.Success;
					}
					if (IsInteger(initialValue))
					{
						value = Enum.ToObject(targetType, initialValue);
						return ConvertResult.Success;
					}
				}

				value = System.Convert.ChangeType(initialValue, targetType, culture);
				return ConvertResult.Success;
			}

#if HAVE_DATE_TIME_OFFSET
            if (initialValue is DateTime dt && targetType == typeof(DateTimeOffset))
            {
                value = new DateTimeOffset(dt);
                return ConvertResult.Success;
            }
#endif

			if (initialValue is byte[] bytes && targetType == typeof(Guid))
			{
				value = new Guid(bytes);
				return ConvertResult.Success;
			}

			if (initialValue is Guid guid && targetType == typeof(byte[]))
			{
				value = guid.ToByteArray();
				return ConvertResult.Success;
			}

			if (initialValue is string s)
			{
				if (targetType == typeof(Guid))
				{
					value = new Guid(s);
					return ConvertResult.Success;
				}
				if (targetType == typeof(Uri))
				{
					value = new Uri(s, UriKind.RelativeOrAbsolute);
					return ConvertResult.Success;
				}
				if (targetType == typeof(TimeSpan))
				{
					value = ParseTimeSpan(s);
					return ConvertResult.Success;
				}
				if (targetType == typeof(byte[]))
				{
					value = System.Convert.FromBase64String(s);
					return ConvertResult.Success;
				}
				if (targetType == typeof(Version))
				{
					if (VersionTryParse(s, out var result))
					{
						value = result;
						return ConvertResult.Success;
					}
					value = null;
					return ConvertResult.NoValidConversion;
				}
				if (typeof(Type).IsAssignableFrom(targetType))
				{
					value = Type.GetType(s, true);
					return ConvertResult.Success;
				}
			}

#if HAVE_BIG_INTEGER
            if (targetType == typeof(BigInteger))
            {
                value = ToBigInteger(initialValue);
                return ConvertResult.Success;
            }
            if (initialValue is BigInteger integer)
            {
                value = FromBigInteger(integer, targetType);
                return ConvertResult.Success;
            }
#endif

#if HAVE_TYPE_DESCRIPTOR
            // see if source or target types have a TypeConverter that converts between the two
            TypeConverter toConverter = TypeDescriptor.GetConverter(initialType);

            if (toConverter != null && toConverter.CanConvertTo(targetType))
            {
                value = toConverter.ConvertTo(null, culture, initialValue, targetType);
                return ConvertResult.Success;
            }

            TypeConverter fromConverter = TypeDescriptor.GetConverter(targetType);

            if (fromConverter != null && fromConverter.CanConvertFrom(initialType))
            {
                value = fromConverter.ConvertFrom(null, culture, initialValue);
                return ConvertResult.Success;
            }
#endif
#if HAVE_ADO_NET
            // handle DBNull
            if (initialValue == DBNull.Value)
            {
                if (ReflectionUtils.IsNullable(targetType))
                {
                    value = EnsureTypeAssignable(null, initialType, targetType);
                    return ConvertResult.Success;
                }

                // cannot convert null to non-nullable
                value = null;
                return ConvertResult.CannotConvertNull;
            }
#endif

			if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract())
			{
				value = null;
				return ConvertResult.NotInstantiableType;
			}

			value = null;
			return ConvertResult.NoValidConversion;
		}