-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
ImmutableHashSet properties allows collection initializer usage without error but initializer has no effect #110279
Comments
Tagging subscribers to this area: @dotnet/area-system-collections |
The collection initializer calls the public ImmutableHashSet<T> Add(T item) method and discards the result. I don't think it will be feasible to change C# to assign the result of the Add method back to the property; that would be a breaking change. But an analyzer could warn about this kind of incorrect usage. CA2009 is already specific to immutable collections. dotnet/roslyn-analyzers#5685 looks related, but it talks about PureAttribute, and ImmutableHashSet<T>.Add(T) does not have PureAttribute. See also #34098 (comment). |
An analyzer warning would probably be good for this case, though I guess it would be waiting on whatever new Pure/MustUseReturnValue attribute ends up getting added to ImmutableHashSet.Add(T)? Not sure how feasible it would be to specifically add an analyzer warning for detecting collection initializer usages of immutable collection types. |
https://github.com/dotnet/roslyn-analyzers/blob/6.0.0/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/Maintainability/DoNotIgnoreMethodResults.cs already recognizes several methods of System.String, despite them not having PureAttribute. I think it would be easy to add something similar for ImmutableHashSet<T>.Add. The ImmutableHashSet<T> type is already listed in https://github.com/dotnet/roslyn-analyzers/blob/6.0.0/src/Utilities/Compiler/WellKnownTypeNames.cs#L146. In the meantime though, the DoNotIgnoreMethodResults analyzer also has "UserDefinedMethodRule", which can be configured in .editorconfig. Perhaps this can be set up to warn about ignoring the result of ImmutableHashSet<T>.Add. |
Alas, no, UserDefinedMethodRule in DoNotIgnoreMethodResults in .NET 9 does not support this case. I tried it like this: Runtime110279.csproj<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project> Program.csusing System;
using System.Collections.Immutable;
var x = new Thing
{
Set =
{
"Abc",
"123"
}
};
x.Set.Add("huh");
Console.WriteLine(x.Set.Count); // 0
public class Thing
{
public ImmutableHashSet<string> Set { get; set; } = ImmutableHashSet<string>.Empty;
} .editorconfigroot = true
[*.cs]
dotnet_diagnostic.CA1806.severity = warning
dotnet_code_quality.CA1806.additional_use_results_methods = Add
# dotnet_code_quality.CA1806.additional_use_results_methods = M:System.Collections.Immutable.ImmutableHashSet<T>.Add(T) and got a CA1806 warning for the The analyzer searches for user-specified methods in OperationKind.Invocation but SharpLab shows Operation: ObjectOrCollectionInitializer; I guess that doesn't match then. But it should be easy to make the analyzer look for OperationKind.ObjectOrCollectionInitializer too and check if the type is ImmutableHashSet<T>. |
If there is some way to have it attribute based on the eventual I do feel this is a necessary analyzer warning though, since methods on immutable collection types already have attribute based warnings. Scenarios where the initializer has already been defined and a refactor changes a collection type from HashSet / List to ImmutableHashSet / ImmutableList could easily create this kind of silent error. Additionally an analyzer fix could offer to change the collection initializer to a C# 12 collection expression instead if init/set accessibility is available. Currently it seems an analyzer could target warnings for initializers with these types for coverage of using System.Collections.Immutable;
using System.Diagnostics;
var x = new Thing
{
ISet = {"a", "b"},
Set = {"a", "b"},
SortedSet = {"a", "b"},
IList = {"a", "b"},
List = {"a", "b"}
};
Debug.Assert(x.ISet.Count == 1);
Debug.Assert(x.Set.Count == 1);
Debug.Assert(x.SortedSet.Count == 1);
Debug.Assert(x.IList.Count == 1);
Debug.Assert(x.List.Count == 1);
public class Thing
{
public IImmutableSet<string> ISet { get; set; } = ["a"];
public ImmutableHashSet<string> Set { get; set; } = ["a"];
public ImmutableSortedSet<string> SortedSet { get; set; } = ["a"];
public IImmutableList<string> IList { get; set; } = ["a"];
public ImmutableList<string> List { get; set; } = ["a"];
}
|
What attribute do you mean? |
I may have confused the Jetbrains IDE warning as a compiler provided one, apparently it works using a |
Description
(System.Collections.Immutable) ImmutableHashSet currently allow collection initializer usage when it is a property, and causes no compilation errors, however the resulting property retains the original assignment.
Reproduction Steps
Expected behavior
One would either expect the collection initializer to make the assignments or, like in the case of ImmutableDictionary, cause a
Error CS0200 : Property or indexer 'ImmutableDictionary<string, string>.this[string]' cannot be assigned to -- it is read only
error, instead of allowing the initializer while not having an effect.Actual behavior
Collection retains the default value assigned and the collection initializer has no effect.
Regression?
No response
Known Workarounds
No response
Configuration
.NET 9 and .NET 8, Windows x64
Other information
No response
The text was updated successfully, but these errors were encountered: