From 6407443ad0e9396063856e4e262763f6d5b554f1 Mon Sep 17 00:00:00 2001 From: Cheng Chen Date: Mon, 15 Jul 2024 16:51:33 +0800 Subject: [PATCH] Fix case insensitive name comparison bug --- src/SmartEnum/SmartFlagEnum.cs | 23 ++++--------------- src/SmartEnum/SmartFlagEnumExtensions.cs | 7 +++--- test/SmartEnum.UnitTests/SmartEnumFromName.cs | 8 +++++++ .../SmartFlagEnumFromName.cs | 4 ++-- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/SmartEnum/SmartFlagEnum.cs b/src/SmartEnum/SmartFlagEnum.cs index 5448367a..66fc47bf 100644 --- a/src/SmartEnum/SmartFlagEnum.cs +++ b/src/SmartEnum/SmartFlagEnum.cs @@ -46,9 +46,6 @@ public abstract class SmartFlagEnum : static readonly Lazy> _fromName = new Lazy>(() => GetAllOptions().ToDictionary(item => item.Name)); - static readonly Lazy> _fromNameIgnoreCase = - new Lazy>(() => GetAllOptions().ToDictionary(item => item.Name, StringComparer.OrdinalIgnoreCase)); - private static IEnumerable GetAllOptions() { Type baseType = typeof(TEnum); @@ -123,19 +120,12 @@ public static IEnumerable FromName(string names, bool ignoreCase = false, if (String.IsNullOrEmpty(names)) ThrowHelper.ThrowArgumentNullOrEmptyException(nameof(names)); - if (ignoreCase) - return FromName(_fromNameIgnoreCase.Value); - else - return FromName(_fromName.Value); - - IEnumerable FromName(Dictionary dictionary) + if (!_fromName.Value.TryGetFlagEnumValuesByName(names, ignoreCase, out var result)) { - if (!dictionary.TryGetFlagEnumValuesByName(names, out var result)) - { - ThrowHelper.ThrowNameNotFoundException(names); - } - return result; + ThrowHelper.ThrowNameNotFoundException(names); } + + return result; } /// @@ -170,10 +160,7 @@ public static bool TryFromName(string names, bool ignoreCase, out IEnumerable(names, out result); - else - return _fromName.Value.TryGetFlagEnumValuesByName(names, out result); + return _fromName.Value.TryGetFlagEnumValuesByName(names, ignoreCase, out result); } /// diff --git a/src/SmartEnum/SmartFlagEnumExtensions.cs b/src/SmartEnum/SmartFlagEnumExtensions.cs index 3989db18..3f3497e1 100644 --- a/src/SmartEnum/SmartFlagEnumExtensions.cs +++ b/src/SmartEnum/SmartFlagEnumExtensions.cs @@ -57,18 +57,19 @@ public static bool IsSmartFlagEnum(this Type type, out Type[] genericArguments) /// /// /// - public static bool TryGetFlagEnumValuesByName(this Dictionary dictionary, string names, out IEnumerable outputEnums) + public static bool TryGetFlagEnumValuesByName(this Dictionary dictionary, string names, bool ignoreCase, out IEnumerable outputEnums) where TEnum : SmartFlagEnum where TValue : IEquatable, IComparable { var outputList = new List(dictionary.Count); var commaSplitNameList = names.Replace(" ", "").Trim().Split(','); - Array.Sort(commaSplitNameList); + var nameComparer = ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; + Array.Sort(commaSplitNameList, nameComparer); foreach (var enumValue in dictionary.Values) { - var result = Array.BinarySearch(commaSplitNameList, enumValue.Name); + var result = Array.BinarySearch(commaSplitNameList, enumValue.Name, nameComparer); if (result >= 0) { outputList.Add(enumValue); diff --git a/test/SmartEnum.UnitTests/SmartEnumFromName.cs b/test/SmartEnum.UnitTests/SmartEnumFromName.cs index d7717e59..3d487672 100644 --- a/test/SmartEnum.UnitTests/SmartEnumFromName.cs +++ b/test/SmartEnum.UnitTests/SmartEnumFromName.cs @@ -34,6 +34,14 @@ public void ReturnsEnumGivenMatchingName() result.Should().BeSameAs(TestEnum.One); } + [Fact] + public void ReturnsEnumGivenMatchingNameIgnoreCase() + { + var result = TestEnum.FromName("ONE", true); + + result.Should().BeSameAs(TestEnum.One); + } + [Fact] public void ReturnsEnumGivenDerivedClass() { diff --git a/test/SmartFlagEnum.UnitTests/SmartFlagEnumFromName.cs b/test/SmartFlagEnum.UnitTests/SmartFlagEnumFromName.cs index 343607ce..2e61db9d 100644 --- a/test/SmartFlagEnum.UnitTests/SmartFlagEnumFromName.cs +++ b/test/SmartFlagEnum.UnitTests/SmartFlagEnumFromName.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -14,7 +14,7 @@ public class SmartFlagEnumFromName [Fact] public void IgnoreCaseReturnsIEnumerableWithSameValues() { - var result = SmartFlagTestEnum.FromName("One, Two", true).ToList(); + var result = SmartFlagTestEnum.FromName("ONE, TWO", true).ToList(); Assert.Equal("One", result[0].Name); Assert.Equal("Two", result[1].Name);