-
Suppose (pre C# 12) I implement my own version of readonly struct MyImmutableArray<T> : IEnumerable<T>//possibly also IImmutableList<T>
{
readonly ImmutableArray<T> _array;//for simplicity
MyImmutableArray(ImmutableArray<T> array)
{
_array = array;
}
public static MyImmutableArray<T> Empty => new(ImmutableArray<T>.Empty);
public MyImmutableArray<T> Add(T item) => new(_array.Add(item));
public int Count => _array.Length;
public T this[int index] => _array[index];
//...
} I can use the type like MyImmutableArray<int> array = MyImmutableArray<int>.Empty.Add(123);
Console.WriteLine(array.Count); Now with C# 12, it is tempting to try the new feature of collection expression, like MyImmutableArray<int> array = [123];
Console.WriteLine(array.Count); And it does compile! Except it does not really work. It translates to MyImmutableArray<int> myImmutableArray = default(MyImmutableArray<int>);
myImmutableArray.Add(123);
MyImmutableArray<int> myImmutableArray2 = myImmutableArray;
Console.WriteLine(myImmutableArray2.Count); There are two problems with this translation:
It is acceptable that a custom type does not automatically work with the new language feature, but this consequence of the new feature, that the code could compile smoothly without any warning to a program with completely unintended behaviour, is a pit of failure and should be avoided. Should the BCL This behaviour is similar to the old feature of collection initializer. There are some options of remedy that I can think of:
I don't know if any similar problem has been suggested before. #5354 is too long to scroll through. Sorry if this turns out to be a duplicate. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
For custom types that can't be built in a normal manner you can define your own builder: |
Beta Was this translation helpful? Give feedback.
-
It's the downside that comes with a powerful syntax that fits many builder patterns. The thing to remember is that 'collection initializer' is one of the strategies that collection expressions can use for construction. Collection initializers can also be written as We've discussed having compiler warnings for |
Beta Was this translation helpful? Give feedback.
-
This is true. Though it has been true for a very long time. Collection-initializers were added to the language, and have all the same problems here (which is why we added the CollectionBuilderAttribute).
One thing was missed here. A collection itself should provide an error when used incorrectly through the use of a custom attribute that comes with it. After all, those collections would still fail if you did |
Beta Was this translation helpful? Give feedback.
For custom types that can't be built in a normal manner you can define your own builder:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/collection-expressions#collection-builder