From 36c9de9cf0cc032179e68be0506f755480854b47 Mon Sep 17 00:00:00 2001 From: workgroupengineering Date: Mon, 30 Sep 2024 12:17:24 +0200 Subject: [PATCH] feat: Enable Rule CA1851 (#16779) * feat: Enable rule CA1851: Possible multiple enumerations of IEnumerable collection * feat: Address rule CA1851 * fix: Address review * fix: address review --- .editorconfig | 2 + .../NumericUpDown/NumericUpDown.cs | 2 +- .../Primitives/TextSelectionCanvas.cs | 22 ++++----- src/Avalonia.Controls/TreeView.cs | 46 ++++++++++++++----- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/.editorconfig b/.editorconfig index 42c6f62e9c..e4a7a6a381 100644 --- a/.editorconfig +++ b/.editorconfig @@ -177,6 +177,8 @@ dotnet_diagnostic.CA1828.severity = warning dotnet_diagnostic.CA1829.severity = warning #CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters dotnet_diagnostic.CA1847.severity = warning +# CA1851: Possible multiple enumerations of IEnumerable collection +dotnet_diagnostic.CA1851.severity = warning #CA1854: Prefer the IDictionary.TryGetValue(TKey, out TValue) method dotnet_diagnostic.CA1854.severity = warning #CA2211:Non-constant fields should not be visible diff --git a/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs b/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs index f0dde6925d..650d06c7c0 100644 --- a/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs +++ b/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs @@ -1137,7 +1137,7 @@ namespace Avalonia.Controls { // extract non-digit characters var currentValueTextSpecialCharacters = currentValueText.Where(c => !char.IsDigit(c)); - var textSpecialCharacters = text.Where(c => !char.IsDigit(c)); + var textSpecialCharacters = text.Where(c => !char.IsDigit(c)).ToArray(); // same non-digit characters on currentValueText and new text => remove them on new Text to parse it again. if (!currentValueTextSpecialCharacters.Except(textSpecialCharacters).Any()) { diff --git a/src/Avalonia.Controls/Primitives/TextSelectionCanvas.cs b/src/Avalonia.Controls/Primitives/TextSelectionCanvas.cs index 6e23495cb1..e4edce964c 100644 --- a/src/Avalonia.Controls/Primitives/TextSelectionCanvas.cs +++ b/src/Avalonia.Controls/Primitives/TextSelectionCanvas.cs @@ -1,10 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; using Avalonia.Controls.Presenters; using Avalonia.Input; -using Avalonia.Interactivity; using Avalonia.Layout; -using Avalonia.Media; using Avalonia.VisualTree; namespace Avalonia.Controls.Primitives @@ -161,7 +160,7 @@ namespace Avalonia.Controls.Primitives { if (position >= _textBox.SelectionEnd) position = _textBox.SelectionEnd - 1; - _textBox.SelectionStart = position; + _textBox.SelectionStart = position; } else { @@ -174,13 +173,12 @@ namespace Avalonia.Controls.Primitives var selectionEnd = _textBox.SelectionEnd; var start = Math.Min(selectionStart, selectionEnd); var length = Math.Max(selectionStart, selectionEnd) - start; + var rects = new List(_presenter.TextLayout.HitTestTextRange(start, length)); - var rects = _presenter.TextLayout.HitTestTextRange(start, length); - - if (rects.Any()) + if (rects.Count > 0) { - var first = rects.First(); - var last = rects.Last(); + var first = rects[0]; + var last = rects[rects.Count -1]; if (handle.SelectionHandleType == SelectionHandleType.Start) handle?.SetTopLeft(ToLayer(first.BottomLeft)); @@ -234,12 +232,12 @@ namespace Avalonia.Controls.Primitives var start = Math.Min(selectionStart, selectionEnd); var length = Math.Max(selectionStart, selectionEnd) - start; - var rects = _presenter.TextLayout.HitTestTextRange(start, length); + var rects = new List(_presenter.TextLayout.HitTestTextRange(start, length)); - if (rects.Any()) + if (rects.Count > 0) { - var first = rects.First(); - var last = rects.Last(); + var first = rects[0]; + var last = rects[rects.Count - 1]; if (!_startHandle.IsDragging) { diff --git a/src/Avalonia.Controls/TreeView.cs b/src/Avalonia.Controls/TreeView.cs index c29dfd583f..98127545f4 100644 --- a/src/Avalonia.Controls/TreeView.cs +++ b/src/Avalonia.Controls/TreeView.cs @@ -11,7 +11,6 @@ using Avalonia.Collections; using Avalonia.Controls.Generators; using Avalonia.Controls.Primitives; using Avalonia.Input; -using Avalonia.Input.Platform; using Avalonia.Interactivity; using Avalonia.Layout; using Avalonia.Threading; @@ -966,20 +965,43 @@ namespace Avalonia.Controls /// /// The items collection. /// The desired items. - private static void SynchronizeItems(IList items, IEnumerable desired) + private static void SynchronizeItems(IList items, List desired) { - var list = items.Cast(); - var toRemove = list.Except(desired).ToList(); - var toAdd = desired.Except(list).ToList(); - - foreach (var i in toRemove) + var itemsCount = items.Count; + if (desired is not null) { - items.Remove(i); - } + var desiredCount = desired.Count; + if (itemsCount == 0 && desiredCount > 0) + { + // Add all desired + foreach (var item in desired) + { + items.Add(item); + } + } + else if (itemsCount > 0 && desiredCount == 0) + { + // Remove all + items.Clear(); + } + // Intersect + else + { + var list = new object[items.Count]; + items.CopyTo(list, 0); + var toRemove = list.Except(desired).ToArray(); + var toAdd = desired.Except(list).ToArray(); - foreach (var i in toAdd) - { - items.Add(i); + foreach (var i in toRemove) + { + items.Remove(i); + } + + foreach (var i in toAdd) + { + items.Add(i); + } + } } } }