From 88caa25215d4034f431a09cc4d3b9033ddf1f788 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 22 Aug 2024 11:11:13 -0500 Subject: [PATCH] Avoid repeat allocations in Enum.TryParse --- .../StyleCop.Analyzers/Settings/JsonHelper.cs | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Settings/JsonHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Settings/JsonHelper.cs index 533e4511d..d433ebd73 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Settings/JsonHelper.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Settings/JsonHelper.cs @@ -7,6 +7,7 @@ namespace StyleCop.Analyzers { using System; using System.Collections.Generic; + using System.Collections.Immutable; using LightJson; /// @@ -82,7 +83,7 @@ internal static string ToStringValue(this JsonValue jsonValue, string elementNam /// The key value pair identifying the JSON value. /// The enum value contained within the JSON value. internal static TEnum ToEnumValue(this KeyValuePair jsonValue) - where TEnum : struct + where TEnum : struct, Enum { if (!jsonValue.Value.IsString) { @@ -90,7 +91,7 @@ internal static TEnum ToEnumValue(this KeyValuePair js } TEnum result; - if (!Enum.TryParse(jsonValue.Value.AsString, true, out result)) + if (!EnumHelper.TryParse(jsonValue.Value.AsString, out result)) { throw new InvalidSettingsException($"{jsonValue.Key} cannot contain enum value '{jsonValue.Value.AsString}'"); } @@ -106,7 +107,7 @@ internal static TEnum ToEnumValue(this KeyValuePair js /// The element name to report in exceptions. /// The enum value contained within the JSON value. internal static TEnum ToEnumValue(this JsonValue jsonValue, string elementName) - where TEnum : struct + where TEnum : struct, Enum { if (!jsonValue.IsString) { @@ -114,7 +115,7 @@ internal static TEnum ToEnumValue(this JsonValue jsonValue, string elemen } TEnum result; - if (!Enum.TryParse(jsonValue.AsString, true, out result)) + if (!EnumHelper.TryParse(jsonValue.AsString, out result)) { throw new InvalidSettingsException($"{elementName} cannot contain enum value '{jsonValue.AsString}'"); } @@ -145,5 +146,25 @@ internal static void AssertIsObject(this KeyValuePair jsonVal throw new InvalidSettingsException($"{jsonValue.Key} must contain an object"); } } + + private static class EnumHelper + where TEnum : struct, Enum + { + private static ImmutableDictionary> values = ImmutableDictionary>.Empty; + + public static bool TryParse(string value, out TEnum result) + { + var successAndResult = ImmutableInterlocked.GetOrAdd( + ref values, + value, + static value => + { + bool success = Enum.TryParse(value, true, out TEnum result); + return new KeyValuePair(success, result); + }); + result = successAndResult.Value; + return successAndResult.Key; + } + } } }