Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an empty IEnumerable argument to a method

I have this method (simplified):

void DoSomething(IEnumerable<int> numbers);

And I invoke it like this:

DoSomething(condition==true?results:new List<int>());

The variable results is formed with a LINQ select condition (IEnumerable).

I was wondering is this List<int>() the best way (the fastest?) to pass an empty collection, or is new int[0] better? Or, something else would be faster, a Collection, etc.? In my example null wouldn't be ok.

like image 902
avance70 Avatar asked May 05 '10 13:05

avance70


People also ask

How do I empty my IEnumerable?

Clear() will empty out an existing IEnumerable. model. Categories = new IEnumerable<whatever>() will create a new empty one. It may not be a nullable type - that would explain why it can't be set to null.

Can IEnumerable be null?

An object collection such as an IEnumerable<T> can contain elements whose value is null. If a source collection is null or contains an element whose value is null , and your query doesn't handle null values, a NullReferenceException will be thrown when you execute the query.

What is IEnumerable interface in C#?

IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface. It is the base interface for all non-generic collections that can be enumerated. This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.

How do I know if IEnumerable has an item?

Use Any() Instead of Count() To See if an IEnumerable Has Any Objects. An IEnumerable is an implementation that supports simple iteration using an enumerator.


2 Answers

I'd use Enumerable.Empty<int>()

DoSometing(condition ? results : Enumerable.Empty<int>());
like image 86
Lee Avatar answered Oct 12 '22 23:10

Lee


@avance70. Not really an answer to original question, but a response to avance70's question about an IEnumerable with just 1 integer value. Would have added it as a comment, but I don't have enough rep to add a comment. If you are interested in a strictly immutable sequence, you have a couple of options:

Generic extension method:

public static IEnumerable<T> ToEnumerable<T>(this T item)
{
  yield return item;
}

Use like this:

foreach (int i in 10.ToEnumerable())
{
  Debug.WriteLine(i); //Will print "10" to output window
}

or this:

int x = 10;
foreach (int i in x.ToEnumerable())
{
  Debug.WriteLine(i); //Will print value of i to output window
}

or this:

int start = 0;
int end = 100;
IEnumerable<int> seq = GetRandomNumbersBetweenOneAndNinetyNineInclusive();

foreach (int i in start.ToEnumerable().Concat(seq).Concat(end.ToEnumerable()))
{
  //Do something with the random numbers, bookended by 0 and 100
}

I recently had a case like the start/end example above where I had to "extract" consecutive values from a sequence (using Skip and Take) and then prepend and append start and end values. The start and end values were interpolated between the last not-extracted value and the first extracted value (for start) and between the last extracted value and the first non-extracted value (for end). The resulting sequence was then operated on again, possibly reversing.

So, if original sequence looked like:

1 2 3 4 5

I might have to extract 3 and 4 and add interpolated values between 2 and 3 and 4 and 5:

2.5 3 4 4.5

Enumerable.Repeat. Use like this:

foreach (int i in Enumerable.Repeat(10,1)) //Repeat "10" 1 time.
{
  DoSomethingWithIt(i);
}

Of course, since these are IEnumerables, they can also be used in conjunction with other IEnumerable operations. Not sure if these are really "good" ideas or not, but they should get the job done.

like image 21
wageoghe Avatar answered Oct 12 '22 23:10

wageoghe