Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert ArrayList usage to List<T> where possible #8140

Open
elachlan opened this issue Nov 9, 2022 · 18 comments
Open

Convert ArrayList usage to List<T> where possible #8140

elachlan opened this issue Nov 9, 2022 · 18 comments
Labels
enhancement Product code improvement that does NOT require public API changes/additions help wanted Good issue for external contributors tenet-performance Improve performance, flag performance regressions across core releases
Milestone

Comments

@elachlan
Copy link
Contributor

elachlan commented Nov 9, 2022

Is your feature request related to a problem? Please describe

Winforms uses Arraylist extensively.

Describe the solution you'd like and alternatives you've considered

Convert Arraylist usage to List<T> to reduce boxing and improve memory utilization.

Will this feature affect UI controls?

N/A

Related: #2644

Remaining occurrences in System.Windows.Forms.Design

File Line Count
src\System\ComponentModel\Design\ExceptionCollection.cs 33
src\System\Windows\Forms\Design\ToolStripItemDataObject.cs 34
src\System\Windows\Forms\Design\ControlDesigner.DesignerControlCollectionCodeDomSerializer.cs 38
src\System\Windows\Forms\Design\UpDownBaseDesigner.cs 63
src\System\Windows\Forms\Design\DesignBindingValueUIHandler.cs 66
src\System\Windows\Forms\Design\ImageListImageEditor.cs 108
src\System\Windows\Forms\Design\ImageCollectionEditor.cs 113
src\System\Windows\Forms\Design\GroupBoxDesigner.cs 124
src\System\Windows\Forms\Design\ComboBoxDesigner.cs 128
src\System\Windows\Forms\Design\LabelDesigner.cs 146
src\System\Windows\Forms\Design\TextBoxBaseDesigner.cs 148
src\System\Windows\Forms\Design\OleDragDropHandler.CfCodeToolboxItem.cs 162
src\System\Windows\Forms\Design\ButtonBaseDesigner.cs 218
src\System\Windows\Forms\Design\Behavior\ContainerSelectorBehavior.cs 230
src\System\Windows\Forms\Design\ToolStripAdornerWindowService.cs 256
src\System\Windows\Forms\Design\BaseContextMenuStrip.cs 290
src\System\Windows\Forms\Design\OleDragDropHandler.ComponentDataObject.cs 302
src\System\ComponentModel\Design\InheritedPropertyDescriptor.cs 308
src\System\Windows\Forms\Design\Behavior\ToolboxItemSnapLineBehavior.cs 338
src\System\ComponentModel\Design\CollectionEditor.cs 347
src\System\Windows\Forms\Design\FormDocumentDesigner.cs 432
src\System\ComponentModel\Design\SelectionService.cs 446
src\System\Windows\Forms\Design\Behavior\SelectionManager.cs 458
src\System\ComponentModel\Design\DesignSurface.cs 491
src\System\Windows\Forms\Design\DesignerFrame.cs 576
src\System\Windows\Forms\Design\ToolStripDesignerUtils.cs 584
src\System\ComponentModel\Design\Serialization\CollectionCodeDomSerializer.cs 648
src\System\Windows\Forms\Design\DesignerUtils.cs 816
src\System\Windows\Forms\Design\Behavior\ResizeBehavior.cs 819
src\System\ComponentModel\Design\Serialization\BasicDesignerLoader.cs 857
src\System\ComponentModel\Design\Serialization\DesignerSerializationManager.cs 896
src\System\Windows\Forms\Design\ToolStripItemBehavior.cs 905
src\System\Windows\Forms\Design\Behavior\DropSourceBehavior.cs 1029
src\System\Windows\Forms\Design\OleDragDropHandler.cs 1045
src\System\Windows\Forms\Design\ToolStripItemDesigner.cs 1177
src\System\ComponentModel\Design\CollectionEditor.CollectionEditorCollectionForm.cs 1223
src\System\ComponentModel\Design\Serialization\CodeDomComponentSerializationService.cs 1471
src\System\ComponentModel\Design\DesignerHost.cs 1615
src\System\Windows\Forms\Design\ToolStripKeyboardHandlingService.cs 1891
src\System\Windows\Forms\Design\ControlDesigner.cs 2205
src\System\Windows\Forms\Design\ToolStripDesigner.cs 2260
src\System\Windows\Forms\Design\ParentControlDesigner.cs 2378
src\System\Windows\Forms\Design\ToolStripMenuItemDesigner.cs 2527
src\System\ComponentModel\Design\Serialization\CodeDomSerializerBase.cs 3020
@elachlan elachlan added api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation untriaged The team needs to look at this issue in the next triage labels Nov 9, 2022
@elachlan elachlan changed the title Convert Arraylist usage to List<T> where possible Convert ArrayList usage to List<T> where possible Nov 9, 2022
@merriemcgaw merriemcgaw removed the untriaged The team needs to look at this issue in the next triage label Nov 9, 2022
@merriemcgaw merriemcgaw added this to the .NET 8.0 milestone Nov 9, 2022
@merriemcgaw merriemcgaw added enhancement Product code improvement that does NOT require public API changes/additions help wanted Good issue for external contributors and removed api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation labels Nov 9, 2022
@ghost ghost modified the milestones: .NET 8.0, Help wanted Nov 9, 2022
@ghost
Copy link

ghost commented Nov 9, 2022

This issue is now marked as "help wanted", and we’re looking for a community volunteer to work on this issue. If we receive no interest in 180 days, we will close the issue. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

@merriemcgaw
Copy link
Member

This is a great idea, and a wonderful place for the community to engage and find the right areas to make changes like this. Of course, we'd need to avoid making this happen on the public surface area 😄

@elachlan
Copy link
Contributor Author

elachlan commented Nov 9, 2022

One issue I have run into is that there are a few collections which expose IList.IsFixedSize, List<T> doesn't have that property. I don't think FixedSize() gets called either. So it might be an idea to change IsFixedSize to just return false?

@Jericho
Copy link
Contributor

Jericho commented Nov 9, 2022

I would be happy to contribute. I will start with combing through the code base to identify the various classes that would be affected.

@elachlan
Copy link
Contributor Author

elachlan commented Nov 9, 2022

@Jericho awesome! Just respond here and I will add it to the issue description.

I think the easiest way to get this done is to fix them one by one instead of batches. I suspect it will be nicer for reviewers and isolates any regressions. It also speeds up the time is takes to merge.

@RussKie
Copy link
Member

RussKie commented Nov 10, 2022

the easiest way to get this done is to fix them one by one instead of batches. I suspect it will be nicer for reviewers and isolates any regressions. It also speeds up the time is takes to merge.

Yes, that's the best way. The smaller and the more targeted a PR - the easier it is to review and faster to merge. That said, it's easier to look at a PR that makes the same changes in 50 files than to look at 50 PRs making the same change in one file. So it's a matter of balance and good judgement.

@Jericho
Copy link
Contributor

Jericho commented Nov 10, 2022

I think the easiest way to get this done is to fix them one by one instead of batches.

@elachlan Thanks for the guidance. I'll also keep @RussKie 's suggestion in mind and combine my PRs into a single, larger PR if there are too many.

@Jericho
Copy link
Contributor

Jericho commented Nov 10, 2022

Here's the list of classes that will benefit from replacing ArrayList with List<T> (I'll continuously maintain this list as I discover more classes):

Here are classes that use an ArrayList and the type of the elements is object. Is it worth it to convert to List<object>?

@elachlan
Copy link
Contributor Author

@dreddy-work I think this can be refactored to remove the usage or ArrayList. But I don't understand the adding of the null value to the list. Can you make sense of it at all?

/// <summary>
/// Retrieves a collection containing a set of standard values for the data type this
/// validator is designed for. This will return null if the data type does not support
/// a standard set of values.
/// </summary>
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context)
{
if (context is not null && context.Instance is ListViewItem item && item.ListView is not null)
{
var list = new ArrayList();
foreach (ListViewGroup group in item.ListView.Groups)
{
list.Add(group);
}
list.Add(null);
return new StandardValuesCollection(list);
}
return null;
}

@elachlan
Copy link
Contributor Author

@dreddy-work when an ICollection or IList is used as the type for a parameter and we are passing in an ArrayList, can we convert our code to pass in List<T>? Its technically compatible, but I am unsure if the expectation is that if we have a public API that is say IList, should the returned value be an ArrayList?

@dreddy-work
Copy link
Member

@dreddy-work when an ICollection or IList is used as the type for a parameter and we are passing in an ArrayList, can we convert our code to pass in List<T>?

internal or private we could change them. General rule on public APIs surface change is, Business justifications vs impact analysis.

Its technically compatible, but I am unsure if the expectation is that if we have a public API that is say IList, should the returned value be an ArrayList?

Can you elaborate on this? I didn't get it fully.

@dreddy-work
Copy link
Member

@dreddy-work I think this can be refactored to remove the usage or ArrayList. But I don't understand the adding of the null value to the list. Can you make sense of it at all?

What i see is, some typeconverters include none or null in standard value collections depending on the type of the converter it was designed for and whether it could be assigned to them. In this case, i see it is intentional.

@halgab
Copy link
Contributor

halgab commented Mar 1, 2023

I also see a few examples of Stacks that can be easily replaced with Stack<T>. Are you interested in such changes? There is no boxing involved in those cases though.

@elachlan
Copy link
Contributor Author

elachlan commented Mar 1, 2023

If the API surface isn't public and then yes. Maybe create a separate issue for it and add a link back here.

@dreddy-work
Copy link
Member

Agree with @elachlan. Just need to be cautious on public APIs and indirect public surface area.

@halgab
Copy link
Contributor

halgab commented Mar 1, 2023

okay, done: #8728

@halgab
Copy link
Contributor

halgab commented Mar 12, 2023

Same question with the internal uses of StringCollection (I found only one to be fair). And does it also deserve its own issue?

@elachlan elachlan added the tenet-performance Improve performance, flag performance regressions across core releases label Nov 3, 2023
@jlechem
Copy link

jlechem commented Sep 28, 2024

Are there still areas I can fix for this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Product code improvement that does NOT require public API changes/additions help wanted Good issue for external contributors tenet-performance Improve performance, flag performance regressions across core releases
Projects
None yet
Development

No branches or pull requests

7 participants