If the enumerable is always a list and you want to clear it instead make the property type IList. If you're model always has a list and you want to clear it instead, then change the model and access the method that way. Show activity on this post. Just create empty list and asign it.
enumerable. Any() is the cleanest way to check if there are any items in the list.
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.
There are times when it's helpful to check a non-repeatable IEnumerable
to see whether or not it's empty. LINQ's Any
doesn't work well for this, since it consumes the first element of the sequence, e.g.
if(input.Any())
{
foreach(int i in input)
{
// Will miss the first element for non-repeatable sequences!
}
}
(Note: I'm aware that there's no need to do the check in this case - it's just an example! The real-world example is performing a Zip
against a right-hand IEnumerable
that can potentially be empty. If it's empty, I want the result to be the left-hand IEnumerable
as-is.)
I've come up with a potential solution that looks like this:
private static IEnumerable<T> NullifyIfEmptyHelper<T>(IEnumerator<T> e)
{
using(e)
{
do
{
yield return e.Current;
} while (e.MoveNext());
}
}
public static IEnumerable<T> NullifyIfEmpty<T>(this IEnumerable<T> source)
{
IEnumerator<T> e = source.GetEnumerator();
if(e.MoveNext())
{
return NullifyIfEmptyHelper(e);
}
else
{
e.Dispose();
return null;
}
}
This can then be used as follows:
input = input.NullifyIfEmpty();
if(input != null)
{
foreach(int i in input)
{
// Will include the first element.
}
}
I have two questions about this:
1) Is this a reasonable thing to do? Is it likely to be problematic from a performance point of view? (I'd guess not, but worth asking.)
2) Is there a better way of achieving the same end goal?
EDIT #1:
Here's an example of a non-repeatable IEnumerable
, to clarify:
private static IEnumerable<int> ReadNumbers()
{
for(;;)
{
int i;
if (int.TryParse(Console.ReadLine(), out i) && i != -1)
{
yield return i;
}
else
{
yield break;
}
}
}
Basically, things which come from user input or a stream, etc.
EDIT #2:
I need to clarify that I'm looking for a solution that preserves the lazy nature of the IEnumerable
- converting it to a list or an array can be an answer in certain circumstances, but isn't what I'm after here. (The real-world reason is that the number of items in the IEnumerable
may be huge in my case, and it's important not to store them all in memory at once.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With