The current ImmutableInterlocked.Update overloads work for each of the immutable collection types except ImmutableArray<T>. It would be valuable, e.g. in dotnet/roslyn#19267, to have an overload which covers this case.
I propose the addition of the following specific methods to ImmutableInterlocked:
public static class ImmutableInterlocked
{
+ public static bool Update<T>(ref ImmutableArray<T> location, Func<ImmutableArray<T>, ImmutableArray<T>> transformer);
+ public static bool Update<T, TArg>(ref ImmutableArray<T> location, Func<ImmutableArray<T>, TArg, ImmutableArray<T>> transformer, TArg transformerArgument);
}
@danmosemsft I added the API details. These methods are rather trivial to implement if the API gets approved.
Related to this - could we have ImmutableHashSet methods as well?
public static bool TryAdd<T>(ref ImmutableHashSet<T> location, T item);
public static bool TryRemove<T>(ref ImmutableHashSet<T> location, T item);
@nrandell That would be a different API request. It seems like a reasonable request, but keep in mind that unlike the issue I described above, it could be implemented in your own code until it gets added here.
Does this still need api work or just review?
cc @safern for Collections.
API proposal is simple, and seems reasonable to have. I just updated the description to add the diff of APIs added and marked as api ready for review
We should make sure that the new overloads don't cause ambiguities but recompiling CoreFx will probably be sufficient.
I'm curious about the semantics here.
Let's say I have:
```C#
internal ImmutableArray
One thread passes this around by ref, e.g.
```C#
Foo(ref _array);
...
Foo(ref ImmutableArray<T> array)
{
for (int i = 0; i < array.Length; i++)
{
Use(array[i]);
}
}
while another thread uses Update:
C#
Update(ref _array, _ => someOtherArray);
The net effect of this will be that the code in Foo is now dangerous and could fail spuriously, as the "immutable" array it's using could be changed out from under it.
Isn't that confusing? Or we just accept that kind of mutability with ImmutableArray?
EDIT: I guess it's no different than some thread just assigning into the field. Nevermind.
I guess it's no different than some thread just assigning into the field. Nevermind.
@stephentoub I don't understand your "Nevermind" here? Isn't the difference that now an immutable array can change during a method that takes it as an argument whereas changing the field doesn't have this effect? Basically ImmutableArray is no longer immutable?
Isn't the difference that now an immutable array can change during a method that takes it as an argument
No. ImmutableArray<T> is a value type. If it's passed by value, then any changes to the original value will have no effect on the copy passed into the method. If it's passed by reference, then it's no different from, say, having a field containing an int, passing a ref to that int into some method, and changing the value in the original field.
Ah of course, apologies I didn't notice that bit.