diff --git a/src/Nest/CommonAbstractions/Infer/ActionIds/ActionIds.cs b/src/Nest/CommonAbstractions/Infer/ActionIds/ActionIds.cs index 478ad5a865e..9eeed7110f7 100644 --- a/src/Nest/CommonAbstractions/Infer/ActionIds/ActionIds.cs +++ b/src/Nest/CommonAbstractions/Infer/ActionIds/ActionIds.cs @@ -11,36 +11,48 @@ public class ActionIds : IUrlParameter, IEquatable { private readonly List _actionIds; - public ActionIds(IEnumerable actionIds) => _actionIds = actionIds?.ToList() ?? new List(); + public ActionIds(IEnumerable actionIds) => _actionIds = actionIds?.ToList(); - public ActionIds(string actionIds) => _actionIds = actionIds.IsNullOrEmpty() - ? new List() - : actionIds.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) - .Select(s => s.Trim()) - .ToList(); - - internal IReadOnlyList Ids => _actionIds; + public ActionIds(string actionIds) + { + if (!actionIds.IsNullOrEmptyCommaSeparatedList(out var arr)) + _actionIds = arr.ToList(); + } private string DebugDisplay => ((IUrlParameter)this).GetString(null); public bool Equals(ActionIds other) { - if (Ids == null && other.Ids == null) return true; - if (Ids == null || other.Ids == null) return false; + if (other == null) return false; + if (_actionIds == null && other._actionIds == null) return true; + if (_actionIds == null || other._actionIds == null) return false; - return Ids.Count == other.Ids.Count && !Ids.Except(other.Ids).Any(); + return _actionIds.Count == other._actionIds.Count && + _actionIds.OrderBy(id => id).SequenceEqual(other._actionIds.OrderBy(id => id)); } - string IUrlParameter.GetString(IConnectionConfigurationValues settings) => string.Join(",", _actionIds); + string IUrlParameter.GetString(IConnectionConfigurationValues settings) => + string.Join(",", _actionIds ?? Enumerable.Empty()); public static implicit operator ActionIds(string actionIds) => - actionIds.IsNullOrEmptyCommaSeparatedList(out var list) ? null : new ActionIds(list); + actionIds.IsNullOrEmptyCommaSeparatedList(out var arr) ? null : new ActionIds(arr); - public static implicit operator ActionIds(string[] actionIds) => actionIds.IsEmpty() ? null : new ActionIds(actionIds); + public static implicit operator ActionIds(string[] actionIds) => + actionIds.IsEmpty() ? null : new ActionIds(actionIds); public override bool Equals(object obj) => obj is ActionIds other && Equals(other); - public override int GetHashCode() => _actionIds.GetHashCode(); + public override int GetHashCode() + { + if (_actionIds == null) return 0; + unchecked + { + var hc = 0; + foreach (var id in _actionIds.OrderBy(id => id)) + hc = hc * 17 + id.GetHashCode(); + return hc; + } + } public static bool operator ==(ActionIds left, ActionIds right) => Equals(left, right); diff --git a/src/Tests/Tests/CommonOptions/ActionIdsTests.cs b/src/Tests/Tests/CommonOptions/ActionIdsTests.cs new file mode 100644 index 00000000000..1b26dd49ec9 --- /dev/null +++ b/src/Tests/Tests/CommonOptions/ActionIdsTests.cs @@ -0,0 +1,27 @@ +using Elastic.Xunit.XunitPlumbing; +using FluentAssertions; +using Nest; + +namespace Tests.CommonOptions +{ + public class ActionIdsTests + { + [U] public void Equal() + { + var actionIds1 = new ActionIds("1,2,3"); + var actionIds2 = new ActionIds(new [] { "3", "2", "1" }); + + actionIds1.Should().Be(actionIds2); + actionIds1.GetHashCode().Should().Be(actionIds2.GetHashCode()); + } + + [U] public void NotEqual() + { + var actionIds1 = new ActionIds("1,2,3,3"); + var actionIds2 = new ActionIds(new [] { "3", "2", "1" }); + + actionIds1.Should().NotBe(actionIds2); + actionIds1.GetHashCode().Should().NotBe(actionIds2.GetHashCode()); + } + } +}