Replies: 22 comments 1 reply
-
@ThadHouse I think that there was some extensive discussion about it at the Roslyn repo, did a quick search but couldn't find the post for it. :) |
Beta Was this translation helpful? Give feedback.
-
After reading though #36, I definitely think just adding IEnumerable, ICollection and IList to the allowed types is going to be much easier then adding a new argument type. Based on my understanding of how params works, adding those types shouldn't break compatibility with old frameworks and should still be compatible with old compilers, just missing the params feature, and requiring full types to be passed. And I'm confused on the boxing discussion in there. Arrays are already reference types, so adding IEnumerable capability wouldn't add any more boxing, right? |
Beta Was this translation helpful? Give feedback.
-
It is not very clear from the discussions and everyone is mixing it - I wonder whether non-generic IEnumerable should be allowed too? |
Beta Was this translation helpful? Give feedback.
-
I would think it should, as it provides parity with 'params object[]'. |
Beta Was this translation helpful? Give feedback.
-
The There's the argument that Then there is the argument to support No CLR changes are necessary. |
Beta Was this translation helpful? Give feedback.
-
I would argue to not use IReadOnlyList and IReadOnlyCollection. Actually I would make it allow both. And the reason for this is that IList does not implement IReadOnlyList, so you cannot pass the same type to both potentially, which takes away the usability. I think thats more of a framework design issue (This has always bugged me and why I don't use IReadOnly collections in my libraries, seems like silly design), but something we have to worry about. In addition, params kind of assumes an uneditable array anyway, so I don't think thats as much of an issue. I would argue that a separate type should be a separate proposal. That would require a new framework and limit compatibility with old frameworks. Whereas params IEnumerable etc would still work 100% with old frameworks, and just require the new compiler. Plus this proposal is just expanding an existing capability, not adding new optimizations. I agree that is a valid proposal, but should be separate from this one, or done at the same time. But this is worthwhile to do even if the Arguments is done as well. |
Beta Was this translation helpful? Give feedback.
-
I was more or less providing a summary of the issue from Roslyn. I agree that Support for other types can be layered on top either out of the gate or down the road. I agree that |
Beta Was this translation helpful? Give feedback.
-
When we have 2 issue like this and #179 what difference between these 2? |
Beta Was this translation helpful? Give feedback.
-
@Thaina This one is just an open discussion about a proposed feature whereas the other tracks the progress and once a design would get proposed by the team we could discuss it there, I hope it helps. |
Beta Was this translation helpful? Give feedback.
-
Only to the same extent that string interpolation |
Beta Was this translation helpful? Give feedback.
-
I would go against the grain here, and suggest IReadOnly* collections only instead of The benefit over just
But arrays are convertible to |
Beta Was this translation helpful? Give feedback.
-
@ashmind e.g. sorting the array doesn't sound very edge-y to me for example. I am quite conservative on this one, I thought the idea was to allow LINQ to be passed around this way, so I would go with What problem does using any other types of collections/lists solve? |
Beta Was this translation helpful? Give feedback.
-
I don't see why we would not allow any and all of the interfaces that arrays already implement.
Today there are APIs where you want to take an IList of values from your caller. But you'd also like your caller to have an easy way to call the API without the verbosity of explicitly instantiating the list. For example: void MyGreatApi(IList<string> strings) { }
// poop... this is ugly:
MyGreatApi(new List<string> { "foo", "bar", baz" }) Today you get around this by writing: void MyGreatApi(params string[] strings) { MyGreatApi((IList<string>)strings); }
void MyGreatApi(IList<string> strings) { }
MyGreatApi("foo", "bar", baz"); This proposal would make it so you could just trivially write: void MyGreatApi(params IList<string> strings) { }
MyGreatApi("foo", "bar", baz"); |
Beta Was this translation helpful? Give feedback.
-
You're right. I was looking at the docs for
Well, at least the ones that make sense. I don't know about |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi For |
Beta Was this translation helpful? Give feedback.
-
It wouldn't. The same way that arrays don't support those operations, even though they implement IList. That's what the IsReadOnly property is for: |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi I see I forgot that array is also |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi |
Beta Was this translation helpful? Give feedback.
-
There's nothing stopping you from legitimately passing an array to functions that take IList. So i see no reason why we would arbitrarily restrict you from passing an array to "params IList". If we forced you to change the type of your signature to something else, then that means you couldn't use params here without either adding an overload, or without it being a breaking change. Both defeat the purpose of providing this feature in the first place. |
Beta Was this translation helpful? Give feedback.
-
params keyword needs to construct a container, as long as IEnumberable.ToArray() is performing enough (0 copy) we can keep using params T[] imo |
Beta Was this translation helpful? Give feedback.
-
imo: Any type that inherits from |
Beta Was this translation helpful? Give feedback.
-
params IEnumerable/ICollection/IList
Summary
Allow params to be declared for the types IEnumerable, ICollection and IList rather than only arrays.
Proposal
C# has always allowed params arrays. However sometimes there are public APIs that would like to take IEnumerable instead of a raw array. In this case, if you wanted to pass something that could take params, you would have to manually create the array first.
Whereas if our function was declared params array, we wouldn't need the temporary array. However, we couldn't pass anything that is not directly an array to this function.
If we allowed params IEnumerable, this would no longer be an issue. We could pass anything that implements IEnumerable, or if params were passed create the array, just like params currently does. You could also do params ICollection and params IList, since arrays implement both implicitly.
This could definitely clean up some public APIs and allow for more types to be passed to functions, while still allowing flexibility.
There are definitely some implementations questions. For instance, do we allow params for anything that we can call a collection initializer on? What type does that create if that type is an interface. Or do we limit to just IEnumerable etc, where we know we have a concrete type we can create.
For the IEnumerable, ICollection and IList case we can always just create a standard array, since an array implements all 3 interfaces.
The other question would be would this require a CLR change, or can it be done entirely by the compiler. How would older compilers see this?
Beta Was this translation helpful? Give feedback.
All reactions