From 3608af59280003a6cd0e7416deca3a9b0ca0b682 Mon Sep 17 00:00:00 2001 From: Tyler Brinkley Date: Fri, 3 Oct 2025 16:56:50 -0500 Subject: [PATCH] Add EnumMemberSelection.DefinitionOrder and EnumMember.DefinitionIndex --- Src/Enums.NET.Test/EnumsTest.cs | 2 + .../DefinitionOrderEnum.cs | 9 ++++ Src/Enums.NET/EnumCache.cs | 44 +++++++++++++------ Src/Enums.NET/EnumMember.cs | 5 +++ Src/Enums.NET/EnumMemberInternal.cs | 8 ++-- Src/Enums.NET/EnumMemberSelection.cs | 6 ++- Src/Enums.NET/Enums.cs | 2 +- 7 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 Src/Enums.NET.TestEnums/DefinitionOrderEnum.cs diff --git a/Src/Enums.NET.Test/EnumsTest.cs b/Src/Enums.NET.Test/EnumsTest.cs index 64fb247..e6d0f3b 100644 --- a/Src/Enums.NET.Test/EnumsTest.cs +++ b/Src/Enums.NET.Test/EnumsTest.cs @@ -138,6 +138,8 @@ public void GetValues() Assert.Equal([DisplayAttributeEnum.Up, DisplayAttributeEnum.Down, DisplayAttributeEnum.Left, DisplayAttributeEnum.Right], GetValues()); Assert.Equal([DisplayAttributeEnum.Left, DisplayAttributeEnum.Up, DisplayAttributeEnum.Down, DisplayAttributeEnum.Right], GetValues(EnumMemberSelection.DisplayOrder)); + Assert.Equal([DefinitionOrderEnum.First, DefinitionOrderEnum.Fourth, DefinitionOrderEnum.Third, DefinitionOrderEnum.Second], GetValues()); + Assert.Equal([DefinitionOrderEnum.First, DefinitionOrderEnum.Second, DefinitionOrderEnum.Third, DefinitionOrderEnum.Fourth], GetValues(EnumMemberSelection.DefinitionOrder)); } [Fact] diff --git a/Src/Enums.NET.TestEnums/DefinitionOrderEnum.cs b/Src/Enums.NET.TestEnums/DefinitionOrderEnum.cs new file mode 100644 index 0000000..910d045 --- /dev/null +++ b/Src/Enums.NET.TestEnums/DefinitionOrderEnum.cs @@ -0,0 +1,9 @@ +namespace EnumsNET.Tests.TestEnums; + +public enum DefinitionOrderEnum +{ + First = 1, + Second = 5, + Third = 3, + Fourth = 2 +} \ No newline at end of file diff --git a/Src/Enums.NET/EnumCache.cs b/Src/Enums.NET/EnumCache.cs index 57c849b..0ce7523 100644 --- a/Src/Enums.NET/EnumCache.cs +++ b/Src/Enums.NET/EnumCache.cs @@ -339,13 +339,19 @@ protected EnumCache(Type enumType, IEnumBridge _members.Length, - EnumMemberSelection.Flags or EnumMemberSelection.Flags | EnumMemberSelection.Distinct or EnumMemberSelection.Flags | EnumMemberSelection.DisplayOrder or EnumMemberSelection.Flags | EnumMemberSelection.DisplayOrder | EnumMemberSelection.Distinct => GetFlagCount(), - EnumMemberSelection.Distinct or EnumMemberSelection.Distinct | EnumMemberSelection.DisplayOrder => _distinctCount, - _ => throw new ArgumentException($"invalid value of {selection.AsString()} for EnumMemberSelection", nameof(selection)), - }; + return _members.Length; + } + if (selection.HasAnyFlags(EnumMemberSelection.Flags)) + { + return GetFlagCount(); + } + if (selection.HasAnyFlags(EnumMemberSelection.Distinct)) + { + return _distinctCount; + } + throw new ArgumentException($"invalid value of {selection.AsString()} for EnumMemberSelection", nameof(selection)); } protected sealed override IReadOnlyList GetMembersInternal(EnumMemberSelection selection, bool cached) => EnumBridge.CreateMembersContainer(GetMembersInternal(selection), GetMemberCount(selection), cached); @@ -356,16 +362,28 @@ public sealed override int GetMemberCount(EnumMemberSelection selection) private IEnumerable> GetMembersInternal(EnumMemberSelection selection) { - IEnumerable> members = selection switch + IEnumerable> members; + if (selection is EnumMemberSelection.All or EnumMemberSelection.DisplayOrder or EnumMemberSelection.DefinitionOrder) { - EnumMemberSelection.All or EnumMemberSelection.DisplayOrder => _members, - EnumMemberSelection.Flags or EnumMemberSelection.Flags | EnumMemberSelection.Distinct or EnumMemberSelection.Flags | EnumMemberSelection.DisplayOrder or EnumMemberSelection.Flags | EnumMemberSelection.DisplayOrder | EnumMemberSelection.Distinct => EnumerateFlagMembers(_allFlags), - EnumMemberSelection.Distinct or EnumMemberSelection.Distinct | EnumMemberSelection.DisplayOrder => _hasDuplicateValues ? _members.Distinct() : _members, - _ => throw new ArgumentException($"invalid value of {selection.AsString()} for EnumMemberSelection", nameof(selection)), - }; + members = _members; + } + else if (selection.HasAnyFlags(EnumMemberSelection.Flags)) + { + members = EnumerateFlagMembers(_allFlags); + } + else if (selection.HasAnyFlags(EnumMemberSelection.Distinct)) + { + members = _hasDuplicateValues ? _members.Distinct() : _members; + } + else + { + throw new ArgumentException($"invalid value of {selection.AsString()} for EnumMemberSelection", nameof(selection)); + } return selection.HasAnyFlags(EnumMemberSelection.DisplayOrder) ? members.OrderBy(m => m.Attributes.Get()?.GetOrder() ?? int.MaxValue) - : members; + : selection.HasAnyFlags(EnumMemberSelection.DefinitionOrder) + ? members.OrderBy(m => m.DefinitionIndex) + : members; } #endregion diff --git a/Src/Enums.NET/EnumMember.cs b/Src/Enums.NET/EnumMember.cs index 64ca421..99715a8 100644 --- a/Src/Enums.NET/EnumMember.cs +++ b/Src/Enums.NET/EnumMember.cs @@ -51,6 +51,11 @@ public abstract class EnumMember : IComparable, IEquatable public AttributeCollection Attributes => Member.Attributes; + /// + /// The enum member's definition index. + /// + public int DefinitionIndex => Member.DefinitionIndex; + private protected EnumMember(EnumMemberInternal member) { Member = member; diff --git a/Src/Enums.NET/EnumMemberInternal.cs b/Src/Enums.NET/EnumMemberInternal.cs index a0412b8..df30b00 100644 --- a/Src/Enums.NET/EnumMemberInternal.cs +++ b/Src/Enums.NET/EnumMemberInternal.cs @@ -38,6 +38,7 @@ internal abstract class EnumMemberInternal : IComparable { public readonly string Name; public readonly AttributeCollection Attributes; + public readonly int DefinitionIndex; private EnumMember? _enumMember; public EnumMember EnumMember @@ -51,10 +52,11 @@ public EnumMember EnumMember private protected abstract EnumMember CreateEnumMember(); - protected EnumMemberInternal(string name, AttributeCollection attributes) + protected EnumMemberInternal(string name, AttributeCollection attributes, int definitionIndex) { Name = name; Attributes = attributes; + DefinitionIndex = definitionIndex; } public abstract void GetValue(ref byte result); @@ -110,9 +112,9 @@ internal sealed class EnumMemberInternal : E private protected override EnumMember CreateEnumMember() => EnumCache.EnumBridge.CreateEnumMember(this); #pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. Gets set soon after creation but cannot be set at creation as EnumCache is not created yet - public EnumMemberInternal(TUnderlying value, string name, AttributeCollection attributes) + public EnumMemberInternal(TUnderlying value, string name, AttributeCollection attributes, int definitionIndex) #pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. - : base(name, attributes) + : base(name, attributes, definitionIndex) { Value = value; } diff --git a/Src/Enums.NET/EnumMemberSelection.cs b/Src/Enums.NET/EnumMemberSelection.cs index 4768a94..17c2ce7 100644 --- a/Src/Enums.NET/EnumMemberSelection.cs +++ b/Src/Enums.NET/EnumMemberSelection.cs @@ -49,5 +49,9 @@ public enum EnumMemberSelection /// /// Include enum members in display order using . /// - DisplayOrder = 4 + DisplayOrder = 4, + /// + /// Include enum members in definition order as opposed to by value. + /// + DefinitionOrder = 8 } diff --git a/Src/Enums.NET/Enums.cs b/Src/Enums.NET/Enums.cs index 893653e..a8fc8ca 100644 --- a/Src/Enums.NET/Enums.cs +++ b/Src/Enums.NET/Enums.cs @@ -113,7 +113,7 @@ private EnumCache CreateCache(IEnumBridge en var attributesArray = Attribute.GetCustomAttributes(field, false); var attributes = attributesArray.Length == 0 ? AttributeCollection.Empty : new AttributeCollection(attributesArray); - var member = new EnumMemberInternal(value, name, attributes); + var member = new EnumMemberInternal(value, name, attributes, i); var index = i; var isPrimary = attributes.Has(); #if NET7_0_OR_GREATER