Replies: 21 comments
-
It helps to say that the collection initializer works with the magic Add method already. Only the compiler seems to also insist the class be IEnumerable, a requirement mburbea would like to get rid of. I already kind of dislike this magic Add method in the first place. Making assumptions based on the method name is the kind loosely-typedness I think we like to avoid as C# developers. A logical thing to introduce then would be an interface IAddable. Thoughts? |
Beta Was this translation helpful? Give feedback.
-
Hmm, according to Object and Collection Initializers (C# Programming Guide):
So the error message, |
Beta Was this translation helpful? Give feedback.
-
@janjoostvanzon,
public void Deconstruct(out T1 p1, out T2 p2...) ... Cat's out the bag on that one... |
Beta Was this translation helpful? Give feedback.
-
@DavidArno: |
Beta Was this translation helpful? Give feedback.
-
@DavidArno |
Beta Was this translation helpful? Give feedback.
-
@DavidArno, I think that the spec here is just a little vague. It also glosses over the fact that it works for structs too.
@janjoostvanzon, there are a couple of other "magic" methods in C# right now. Like the duck-typing around foreach. Type-safety has nothing to do with it. |
Beta Was this translation helpful? Give feedback.
-
Am I missing something? I thought foreach worked with IEnumerable and |
Beta Was this translation helpful? Give feedback.
-
@janjoostvanzon Or anything that happens to have a |
Beta Was this translation helpful? Give feedback.
-
See the |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
This is true, but I'd argue that it's still duck typed because those marker interfaces are not used if public struct methods are available. IIRC. |
Beta Was this translation helpful? Give feedback.
-
The simple things in life make me happy. That statement (regardless of its likely precision and accuracy) is going to keep me chuckling to myself for quite some time... 😀 |
Beta Was this translation helpful? Give feedback.
-
@HaloFour you going to test this or shall I? 😄 Edit: LinqPad shows direct struct calls, no casting, so no runtime enforcement of interfaces. = duck typing. |
Beta Was this translation helpful? Give feedback.
-
Sorry to be unaware of this feature of foreach. This source suggests I have to use IEnumerable /
Would it be strange to suggest that it would be easier for interface implementation to be insisted by the compiler and does that magic performance improvement under the hood? |
Beta Was this translation helpful? Give feedback.
-
From the specification:
So the compiler obeys the specification, no matter that other pages are more vague. I understand your feature request is to remove this requirement. |
Beta Was this translation helpful? Give feedback.
-
I think the requirement of IEnumerable was meant to catch usage of collection initializers with classes that just happened to have an Add method but were not collections. |
Beta Was this translation helpful? Give feedback.
-
@gafter, you are correct. Sorry I meant to say that guide was a bit vague. Yes, I'd like to remove it. @mattwar, yes. I realize that things like a |
Beta Was this translation helpful? Give feedback.
-
@DavidArno That documentation page is wrong, so I have submitted a PR fixing it in the docs.microsoft version of that page: dotnet/docs#1961. |
Beta Was this translation helpful? Give feedback.
-
Code like |
Beta Was this translation helpful? Give feedback.
-
@svick, No. That would be a breaking change. To quote what I said in response to @mattwar.
For types that are |
Beta Was this translation helpful? Give feedback.
-
A breaking change, but perhaps one for the better. Either way, maybe it would be best to have a way through which developers can provide hints to the compiler as to how best emit for a collection initializer? I created #463 thinking that might address these concerns. |
Beta Was this translation helpful? Give feedback.
-
Allow collection-initializers on non-IEnumerables
Summary
Relax the current compilation error CS1922, and allow the usage of collection initializer on any type provided that there is a public
Add
method that returnsbool
orvoid
or an in-scope extension method namedAdd
that returns bool or void.Add may also be generic to allow scenarios like the following to work::
(this is existing behavior)
To clarify:
The method must return
bool
orvoid
to avoid unintentional confusion around types like aComplexNumber
, where theAdd
method returns a new instance.However, for
IEnumerable
types nothing changes. Thus this can (and still will) compile despite being very wrong.Motivation
Simply put, not every collection should be enumerated. Additionally, non-enumerable types (like builders) would benefit from being able to use this simplified syntax.
For symmetry purposes dictionary initializers (e.g.
new MyType{[3]="k"}
) do not require either a getter orIEnumerable
to be implemented, so it seems an unusual onus to require enumerability to use a collection initializer.Drawbacks
TBD?
Alternatives
You can currently implement
IEnumerable
, and implement the interface explicitly. However, someone can cast your type toIEnumerable
or iterate over your collection with aforeach
loop.One alternative could be using a
params T[]
parameter on your constructor. However, this disables the use of fluctuating generic signatures. Additionally, this requires allocating an array which maybe in-optimal depending on the situation.Finally, you can also use fluent method chaining. This can work, but there is no language support for this effort and so it could be very verbose and doesn't play well with inheritance. (Requiring re-implementation to get the right behavior.)
e.g.
Beta Was this translation helpful? Give feedback.
All reactions