From fbf59e12c73a7a15191455e47498e432cae457e8 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Thu, 22 Nov 2018 10:04:56 +0100 Subject: [PATCH] [C] avoid Enum.TryParse for resolving NamedSizes (#4501) Enum.TryParse is quite expensive. replace that by simple value check for known values. Keep the TryParse as a safeguard in case we ever add new values to it. --- Xamarin.Forms.Core/FontSizeConverter.cs | 61 ++++++++++++++++--------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/Xamarin.Forms.Core/FontSizeConverter.cs b/Xamarin.Forms.Core/FontSizeConverter.cs index 9f3622ad3..7fb2058b9 100644 --- a/Xamarin.Forms.Core/FontSizeConverter.cs +++ b/Xamarin.Forms.Core/FontSizeConverter.cs @@ -4,30 +4,40 @@ using Xamarin.Forms.Xaml; namespace Xamarin.Forms { - [Xaml.TypeConversion(typeof(double))] + [TypeConversion(typeof(double))] public class FontSizeConverter : TypeConverter, IExtendedTypeConverter { [Obsolete("IExtendedTypeConverter.ConvertFrom is obsolete as of version 2.2.0. Please use ConvertFromInvariantString (string, IServiceProvider) instead.")] object IExtendedTypeConverter.ConvertFrom(CultureInfo culture, object value, IServiceProvider serviceProvider) - { - return ((IExtendedTypeConverter)this).ConvertFromInvariantString(value as string, serviceProvider); - } + => ((IExtendedTypeConverter)this).ConvertFromInvariantString(value as string, serviceProvider); object IExtendedTypeConverter.ConvertFromInvariantString(string value, IServiceProvider serviceProvider) { - if (value != null) - { - double size; - if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out size)) + if (value != null) { + value = value.Trim(); + if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out double size)) return size; + var ignoreCase = (serviceProvider?.GetService(typeof(IConverterOptions)) as IConverterOptions)?.IgnoreCase ?? false; - NamedSize namedSize; - if (Enum.TryParse(value, ignoreCase, out namedSize)) - { - Type type; - var valueTargetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; - type = valueTargetProvider != null ? valueTargetProvider.TargetObject.GetType() : typeof(Label); - return Device.GetNamedSize(namedSize, type, false); + var sc = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; + NamedSize? namedSize = null; + + if (value.Equals(nameof(NamedSize.Default), sc)) + namedSize = NamedSize.Default; + else if (value.Equals(nameof(NamedSize.Micro), sc)) + namedSize = NamedSize.Micro; + else if (value.Equals(nameof(NamedSize.Small), sc)) + namedSize = NamedSize.Small; + else if (value.Equals(nameof(NamedSize.Medium), sc)) + namedSize = NamedSize.Medium; + else if (value.Equals(nameof(NamedSize.Large), sc)) + namedSize = NamedSize.Large; + else if (Enum.TryParse(value, ignoreCase, out NamedSize ns)) + namedSize = ns; + + if (namedSize.HasValue) { + var type = serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget valueTargetProvider ? valueTargetProvider.TargetObject.GetType() : typeof(Label); + return Device.GetNamedSize(namedSize.Value, type, false); } } throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", value, typeof(double))); @@ -35,13 +45,22 @@ namespace Xamarin.Forms public override object ConvertFromInvariantString(string value) { - if (value != null) - { - double size; - if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out size)) + if (value != null) { + if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out double size)) return size; - NamedSize namedSize; - if (Enum.TryParse(value, out namedSize)) + value = value.Trim(); + + if (value.Equals(nameof(NamedSize.Default), StringComparison.Ordinal)) + return Device.GetNamedSize(NamedSize.Default, typeof(Label), false); + if (value.Equals(nameof(NamedSize.Micro), StringComparison.Ordinal)) + return Device.GetNamedSize(NamedSize.Micro, typeof(Label), false); + if (value.Equals(nameof(NamedSize.Small), StringComparison.Ordinal)) + return Device.GetNamedSize(NamedSize.Small, typeof(Label), false); + if (value.Equals(nameof(NamedSize.Medium), StringComparison.Ordinal)) + return Device.GetNamedSize(NamedSize.Medium, typeof(Label), false); + if (value.Equals(nameof(NamedSize.Large), StringComparison.Ordinal)) + return Device.GetNamedSize(NamedSize.Large, typeof(Label), false); + if (Enum.TryParse(value, out NamedSize namedSize)) return Device.GetNamedSize(namedSize, typeof(Label), false); } throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", value, typeof(double)));