question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow support for params IEnumerable<T> methods

See original GitHub issue

Currently, C# only supports params T[], however it is rare that I actually need an array for my method. More often than not, I merely want iteration or to perform some sort of LINQ operators against the parameter. In fact, it is common for libraries to declare a version of the method that takes an IEnumerable<T> and a T[], and have the T[] version call the IEnumerable<T> variant.

The implementation detail could still be that an array is made at the call site and sent to the method, the benefit is to simply avoid having to create the extra overload.

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Reactions:27
  • Comments:99 (27 by maintainers)

github_iconTop GitHub Comments

12reactions
jaredparcommented, Jan 19, 2015

If we are going to invest in a new params type I would like to see us invest in one that is more efficient than either T[] or IEnumerable<T> but equally inclusive.

Today low level APIs which expose a params method typically end up exposing several other non-params overloads in order to avoid call site allocation of the array for small numbers of arguments. It’s not uncommon at all to see the following:

WriteLine(params object[] args)
WriteLine(object arg)
WriteLine(object arg1, object arg2)

...

// The above pattern lets the following bind without the object[] allocation
WriteLine("dog");

Switching to IEnumerable<T> would not help here and would in fact make it works because it creates two allocations for a small number of arguments:

  • The collection allocation at the call site
  • The `IEnumerator<T> allocation in the caller

An idea we’ve sketched around a few times is a struct of the following nature:

struct Arguments<T> : IEnumerable<T>
{
  T _arg1; 
  T _arg2;
  IEnumerable<T> _enumerable;
  int _count;

  // struct based enumerator 
  // index which intelligently switches between T fields and enumerable
}

WriteLine(params Arguments<T> args)

The Arguments<T> struct represents a collection of arguments. In can be built off of individual arguments or a collection. In the case of a small number of individual arguments, which for many APIs is the predominant use case, it can do so allocation free. The compiler would be responsible for picking the best method of constructing Arguments<T> at the callsite.

3reactions
Pzixelcommented, Jun 20, 2016

@HaloFour

Any such method is already taking that risk if they don’t first check the IsReadOnly property. The IList interface makes no claim that the implementation is writable. Arrays have always implemented these interfaces.

And this is one of my least-favorite feature in BCL. Standad collection hierarchy is so ugly, and it seems that it will be as it is forever, becuase backward compatibility is the holy cow for Microsoft. It’s bizzare, that array implements IList, and half of methods throws NotAllowedException. Is it statically typed language or not?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Params IEnumerable<T> c# - Stack Overflow
The "params enumerable" feature has been thought of and designed. ... simply allow you to use IEnumerable as the type of the params...
Read more >
Allow params method parameters to be IEnumerable, not ...
The latter would be nice so I could pass in any IEnumerable<T> without calling ToArray() on it. Visual Studiowindows 10.0visual studio 2019 ...
Read more >
c# - params T[] vs IEnumerable<T> as parameter type
So tailor your method to your audience. Those string you pass, do they come as hardcoded string from the developer? Like .Allow("GET", "PUT" ......
Read more >
An Interesting Params Gotcha In C# – .NET Core Tutorials
Let's say I have a method that looks like so : static void Call(IEnumerable<object> input) { Console.WriteLine("List Object"); }. Pretty normal.
Read more >
IEnumerable<T> Interface (System.Collections.Generic)
Exposes the enumerator, which supports a simple iteration over a collection of ... This allows a generic collection to be passed to a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found