Checking for empty or null List<string> - c#

I have a List where sometimes it is empty or null. I want to be able to check if it contains any List-item and if not then add an object to the List.
// I have a list, sometimes it doesn't have any data added to it
var myList = new List<object>();
// Expression is always false
if (myList == null)
Console.WriteLine("List is never null");
if (myList[0] == null)
myList.Add("new item");
//Errors encountered: Index was out of range. Must be non-negative and less than the size of the collection.
// Inner Exception says "null"

Try the following code:
if ( (myList!= null) && (!myList.Any()) )
{
// Add new item
myList.Add("new item");
}
A late EDIT because for these checks I now like to use the following solution.
First, add a small reusable extension method called Safe():
public static class IEnumerableExtension
{
public static IEnumerable<T> Safe<T>(this IEnumerable<T> source)
{
if (source == null)
{
yield break;
}
foreach (var item in source)
{
yield return item;
}
}
}
And then, you can do the same like:
if (!myList.Safe().Any())
{
// Add new item
myList.Add("new item");
}
I personally find this less verbose and easier to read. You can now safely access any collection without the need for a null check.
And another EDIT, which doesn't require an extension method, but uses the ? (Null-conditional) operator (C# 6.0):
if (!(myList?.Any() ?? false))
{
// Add new item
myList.Add("new item");
}

For anyone who doesn't have the guarantee that the list will not be null, you can use the null-conditional operator to safely check for null and empty lists in a single conditional statement:
if (list?.Any() != true)
{
// Handle null or empty list
}

Checkout L-Four's answer.
A less-efficient answer:
if(myList.Count == 0){
// nothing is there. Add here
}
Basically new List<T> will not be null but will have no elements. As is noted in the comments, the above will throw an exception if the list is uninstantiated. But as for the snippet in the question, where it is instantiated, the above will work just fine.
If you need to check for null, then it would be:
if(myList != null && myList.Count == 0){
// The list is empty. Add something here
}
Even better would be to use !myList.Any() and as is mentioned in the aforementioned L-Four's answer as short circuiting is faster than linear counting of the elements in the list.

What about using an extension method?
public static bool AnyOrNotNull<T>(this IEnumerable<T> source)
{
if (source != null && source.Any())
return true;
else
return false;
}

An easy way to combine myList == null || myList.Count == 0 would be to use the null coalescing operator ??:
if ((myList?.Count ?? 0) == 0) {
//My list is null or empty
}

if (myList?.Any() == true)
{
...
}
I find this the most convenient way. '== true' checks the value of the nullable bool implied by '?.Any()

Assuming that the list is never null, the following code checks if the list is empty and adds a new element if empty:
if (!myList.Any())
{
myList.Add("new item");
}
If it is possible that the list is null, a null check must be added before the Any() condition:
if (myList != null && !myList.Any())
{
myList.Add("new item");
}
In my opinion, using Any() instead of Count == 0 is preferable since it better expresses the intent of checking if the list has any element or is empty.
However, considering the performance of each approach, using Any() is generally slower than Count.

I was wondering nobody suggested to create own extension method more readable name for OP's case.
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
if (source == null)
{
return true;
}
return source.Any() == false;
}

The IsNullOrEmpty() extension method is a very elegant and human-readable way of implementing this, so I decided to use it. However, you can achieve the same thing without extension methods, too.
Let's say we have an object named list of type List<T> (e.g. List<string>). If you want to know whether the list has items, you can say:
list?.Count > 0 // List<T> has items
This will return false for an empty list and also if the list itself is a null object, true otherwise.
So the only thing you need to do if you want to check whether the list doesn't have any items is to invert the above expression:
!(list?.Count > 0) // List<T> is null or empty
This will return true for an empty list and also if the list itself is a null object, false otherwise. Exactly what you expect from an IsNullOrEmpty evaluation. Just a little cryptic!
As List<T> implements IEnumerable<T>, you can implement the same thing less specific, but this will possibly make the evaluation slower:
list?.Any() != true // IEnumerable<T> is null or empty

Your List has no items, that's why access to non-existing 0th item
myList[0] == null
throws Index was out of range exception; when you want to access n-th item check
if (myList.Count > n)
DoSomething(myList[n])
in your case
if (myList.Count > 0) // <- You can safely get 0-th item
if (myList[0] == null)
myList.Add("new item");

myList[0] gets the first item in the list. Since the list is empty there is no item to get and you get the IndexOutOfRangeException instead.
As other answers here have shown, in order to check if the list is empty you need to get the number of elements in the list (myList.Count) or use the LINQ method .Any() which will return true if there are any elements in the list.

Most answers here focused on how to check if a collection is Empty or Null which was quite straight forward as demonstrated by them.
Like many people here, I was also wondering why does not Microsoft itself provide such a basic feature which is already provided for String type (String.IsNullOrEmpty())? Then I encountered this guideline from Microsoft where it says:
X DO NOT return null values from collection properties or from methods returning collections. Return an empty collection or an empty array instead.
The general rule is that null and empty (0 item) collections or arrays
should be treated the same.
So, ideally you should never have a collection which is null if you follow this guideline from Microsoft. And that will help you to remove unnecessary null checking which ultimately will make your code more readable. In this case, someone just need to check : myList.Any() to find out whether there is any element present in the list.
Hope this explanation will help someone who will face same problem in future and wondering why isn't there any such feature to check whether a collection is null or empty.

You can check the list is empty or not in multiple ways
1)Checklist is null and then check count is greater than zero like below:-
if (myList != null && myList.Count > 0)
{
//List has more than one record.
}
2)Checklist null and count greater than zero using LINQ query like below:-
if (myList?.Any() == true)
{
//List has more than one record.
}

List in c# has a Count property. It can be used like so:
if(myList == null) // Checks if list is null
// Wasn't initialized
else if(myList.Count == 0) // Checks if the list is empty
myList.Add("new item");
else // List is valid and has something in it
// You could access the element in the list if you wanted

If you want a single line condition that checks both null and empty, you can use
if (list == null ? true : (!list.Any()))
This will work in older framework versions where the null-conditional operator is not available.

Try and use:
if(myList.Any())
{
}
Note: this assmumes myList is not null.

You can use Count property of List in c#
please find below code which checks list empty and null both in a single condition
if(myList == null || myList.Count == 0)
{
//Do Something
}

public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
return !(items?.Any() ?? false);
}
This extension method helps you determine if a list is either null or empty.
It can be used as follows:
using System;
using System.Linq;
using System.Collections.Generic;
public static class IEnumerableExtensions
{
public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
return !(items?.Any() ?? false);
}
}
public class Program
{
public static void Main()
{
List<string> test1 = null;;
Console.WriteLine($"List 1 is empty: {test1.IsNullOrEmpty()}");
//Output: List 1 is empty: True
var test2 = new System.Collections.Generic.List<string>();
System.Console.WriteLine($"List 2 is empty: {test2.IsNullOrEmpty()}");
//Output: List 2 is empty: True
var test3 = new System.Collections.Generic.List<string>();
test3.Add("test");
System.Console.WriteLine($"List 3 is empty: {test3.IsNullOrEmpty()}");
//Output: List 3 is empty: False
}
}

We can validate like below with Extension methods. I use them for all of my projects.
var myList = new List<string>();
if(!myList.HasValue())
{
Console.WriteLine("List has value(s)");
}
if(!myList.HasValue())
{
Console.WriteLine("List is either null or empty");
}
if(myList.HasValue())
{
if (!myList[0].HasValue())
{
myList.Add("new item");
}
}
/// <summary>
/// This Method will return True if List is Not Null and it's items count>0
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items"></param>
/// <returns>Bool</returns>
public static bool HasValue<T>(this IEnumerable<T> items)
{
if (items != null)
{
if (items.Count() > 0)
{
return true;
}
}
return false;
}
/// <summary>
/// This Method will return True if List is Not Null and it's items count>0
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items"></param>
/// <returns></returns>
public static bool HasValue<T>(this List<T> items)
{
if (items != null)
{
if (items.Count() > 0)
{
return true;
}
}
return false;
}
/// <summary>
/// This method returns true if string not null and not empty
/// </summary>
/// <param name="ObjectValue"></param>
/// <returns>bool</returns>
public static bool HasValue(this string ObjectValue)
{
if (ObjectValue != null)
{
if ((!string.IsNullOrEmpty(ObjectValue)) && (!string.IsNullOrWhiteSpace(ObjectValue)))
{
return true;
}
}
return false;
}

We can add an extension to create an empty list
public static IEnumerable<T> Nullable<T>(this IEnumerable<T> obj)
{
if (obj == null)
return new List<T>();
else
return obj;
}
And use like this
foreach (model in models.Nullable())
{
....
}

I personally create an extension method for the IEnumerable class which I call IsNullOrEmpty(). Because it applies to all implementations of IEnumerable, it works for a List, but also for a String, IReadOnlyList, etc.
My implementation is simply this:
public static class ExtensionMethods
{
public static bool IsNullOrEmpty(this IEnumerable enumerable)
{
if (enumerable is null) return true;
foreach (var element in enumerable)
{
//If we make it here, it means there are elements, and we return false
return false;
}
return true;
}
}
I can then use the method on a list as follows:
var myList = new List<object>();
if (myList.IsNullOrEmpty())
{
//Do stuff
}

I just wanted to add an answer here since this is the top hit on Google for checking if a List is null or empty. For me .Any is not recognized. If you want to check without creating an extension method you can do it like this which is pretty simple:
//Check that list is NOT null or empty.
if (myList != null && myList.Count > 0)
{
//then proceed to do something, no issues here.
}
//Check if list is null or empty.
if (myList == null || myList.Count == 0)
{
//error handling here for null or empty list
}
//checking with if/else-if/else
if (myList == null)
{
//null handling
}
else if(myList.Count == 0)
{
//handle zero count
}
else
{
//no issues here, proceed
}
If there is a possibility the list could be null then you must check for null first - if you try to check the count first and the list happens to be null then it will throw an error. && and || are short-circuit operators, so the second condition is only evaluated if the first is not satisfied.

You can add this IEnumerable extension method that returns true if the source sequence either contains any elements and is not null. Otherwise returns false.
public static class IEnumerableExtensions
{
public static bool IsNotNullNorEmpty<T>(this IEnumerable<T> source)
=> source?.Any() ?? false;
}

Because you initialize myList with 'new', the list itself will never be null.
But it can be filled with 'null' values.
In that case .Count > 0 and .Any() will be true. You can check this with the .All(s => s == null)
var myList = new List<object>();
if (myList.Any() || myList.All(s => s == null))

This is able to solve your problem
`if(list.Length > 0){
}`

Related

Check if lists are disjoint

I need to check if two lists have any elements in common. I just need a yes/no - I don't need the actual list of common elements.
I could use Enumerable.Intersect() but this does actually return the set of matching items which seems like it would require extra overhead. Is there a better method for checking if lists are disjoint?
My lists do actually happen to be List<T> but that isn't crucial and I could use something like HashSet (say) if that were more convenient. i.e., I don't want to unnecessarily constrain potential solutions.
Grazie mille
Simplest version (using Intersect):
public bool Compare(List<T> firstCollection, List<T> secondCollection)
{
return firstCollection.Intersect(secondCollection).Any();
}
Only caveat is either T shall implement IEquatable<T> or pass custom IEqualityComparer<T> in the Intersect call. Also make sure that GetHashCode is overriden along with Equals
Edit 1:
This version using Dictionary will not just provide boolean comparison, but also the elements. In this solution Dictionary in the end would contain data related to number of intersecting elements, number of elements in one of the collection but not in another, so fairly durable. This solution also has IEquatable<T> requirement
public bool CompareUsingDictionary(IEnumerable<T> firstCollection, IEnumerable<T> secondCollection)
{
// Implementation needs overiding GetHashCode methods of the object base class in the compared type
// Obviate initial test cases, if either collection equals null and other doesn't then return false. If both are null then return true.
if (firstCollection == null && secondCollection != null)
return false;
if (firstCollection != null && secondCollection == null)
return false;
if (firstCollection == null && secondCollection == null)
return true;
// Create a dictionary with key as Hashcode and value as number of occurences
var dictionary = new Dictionary<int, int>();
// If the value exists in first list , increase its count
foreach (T item in firstCollection)
{
// Get Hash for each item in the list
int hash = item.GetHashCode();
// If dictionary contains key then increment
if (dictionary.ContainsKey(hash))
{
dictionary[hash]++;
}
else
{
// Initialize he dictionary with value 1
dictionary.Add(hash, 1);
}
}
// If the value exists in second list , decrease its count
foreach (T item in secondCollection)
{
// Get Hash for each item in the list
int hash = item.GetHashCode();
// If dictionary contains key then decrement
if (dictionary.ContainsKey(hash))
{
dictionary[hash]--;
}
else
{
return false;
}
}
// Check whether any value is 0
return dictionary.Values.Any(numOfValues => numOfValues == 0);
}

Check if IEnumerable has ANY rows without enumerating over the entire list

I have the following method which returns an IEnumerable of type T. The implementation of the method is not important, apart from the yield return to lazy load the IEnumerable. This is necessary as the result could have millions of items.
public IEnumerable<T> Parse()
{
foreach(...)
{
yield return parsedObject;
}
}
Problem:
I have the following property which can be used to determine if the IEnumerable will have any items:
public bool HasItems
{
get
{
return Parse().Take(1).SingleOrDefault() != null;
}
}
Is there perhaps a better way to do this?
IEnumerable.Any() will return true if there are any elements in the sequence and false if there are no elements in the sequence. This method will not iterate the entire sequence (only maximum one element) since it will return true if it makes it past the first element and false if it does not.
Similar to Howto: Count the items from a IEnumerable<T> without iterating? an Enumerable is meant to be a lazy, read-forward "list", and like quantum mechanics the act of investigating it alters its state.
See confirmation: https://dotnetfiddle.net/GPMVXH
var sideeffect = 0;
var enumerable = Enumerable.Range(1, 10).Select(i => {
// show how many times it happens
sideeffect++;
return i;
});
// will 'enumerate' one item!
if(enumerable.Any()) Console.WriteLine("There are items in the list; sideeffect={0}", sideeffect);
enumerable.Any() is the cleanest way to check if there are any items in the list. You could try casting to something not lazy, like if(null != (list = enumerable as ICollection<T>) && list.Any()) return true.
Or, your scenario may permit using an Enumerator and making a preliminary check before enumerating:
var e = enumerable.GetEnumerator();
// check first
if(!e.MoveNext()) return;
// do some stuff, then enumerate the list
do {
actOn(e.Current); // do stuff with the current item
} while(e.MoveNext()); // stop when we don't have anything else
The best way to answer this question, and to clear all doubts, is to see what the 'Any' function does.
public static bool Any<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
using (IEnumerator<TSource> e = source.GetEnumerator()) {
if (e.MoveNext()) return true;
}
return false;
}
https://github.com/microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs

Check if all List Items have the same member value in C#

I'm searching for a simple and fast way to check if all my Listitems have the same value for a member.
foreach (Item item in MyList)
{
Item.MyMember = <like all other>;
}
EDIT:
I forgot one thing: If one of this members (its a string) is String.Empty and all other items have the same string it should be true too! Sorry i forgot this.
EDIT: Okay, after the new requirement has
bool allSame = !MyList.Select(item => item.MyMember)
.Where(x => !string.IsNullOrEmpty(x))
.Distinct()
.Skip(1)
.Any();
That avoids you having to take a first step of finding one sample value to start with. (And it will still exit as soon as it finds the second value, of course.)
It also only iterates over the sequence once, which may be important if it's not really a repeatable sequence. Not a problem if it's a List<T> of course.
EDIT: To allay concerns over Skip, from the documentation:
If source contains fewer than count elements, an empty IEnumerable<T> is returned. If count is less than or equal to zero, all elements of source are yielded.
Your own solution is simple enough already, but if you wanted to abstract away the loop and write it more expressively, you could use Linq.
bool allSame = MyList.All(item => item.MyMember == someValue);
using System.Linq;
…
if (myList.Any()) // we need to distinguish between empty and non-empty lists
{
var value = myList.First().MyMember;
return myList.All(item => item.MyMember == value);
}
else
{
return true; // or false, if that is more appropriate for an empty list
}
Here is a generic one that works for all version of .NET beginning with 2.0:
public static bool AllSameByProperty<TItem, TProperty>(IEnumerable<TItem> items, Converter<TItem, TProperty> converter)
{
TProperty value = default(TProperty);
bool first = true;
foreach (TItem item in items)
{
if (first)
{
value = converter.Invoke(item);
first = false;
continue;
}
TProperty newValue = converter.Invoke(item);
if(value == null)
{
if(newValue != null)
{
return false;
}
continue;
}
if (!value.Equals(newValue))
{
return false;
}
}
return true;
}
Its usage in C# 2.0:
AllSameByProperty(list, delegate(MyType t) { return t.MyProperty; });
Its usage in C# 3.0:
AllSameByProperty(list, t => t.MyProperty);
Iam doing like so:
Item item = MyList.FirstOrDefault(x=>x.MyMember != valueToMatch);
bool allMembersSame = item == null;
I think this is the shortest and most elegant solution:
bool allSame = list.GroupBy(item => item.TheProperty).Count == 1;

Why does .NET foreach loop throw NullRefException when collection is null?

So I frequently run into this situation... where Do.Something(...) returns a null collection, like so:
int[] returnArray = Do.Something(...);
Then, I try to use this collection like so:
foreach (int i in returnArray)
{
// do some more stuff
}
I'm just curious, why can't a foreach loop operate on a null collection? It seems logical to me that 0 iterations would get executed with a null collection... instead it throws a NullReferenceException. Anyone know why this could be?
This is annoying as I'm working with APIs that aren't clear on exactly what they return, so I end up with if (someCollection != null) everywhere.
Well, the short answer is "because that's the way the compiler designers designed it." Realistically, though, your collection object is null, so there's no way for the compiler to get the enumerator to loop through the collection.
If you really need to do something like this, try the null coalescing operator:
int[] array = null;
foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}
A foreach loop calls the GetEnumerator method.
If the collection is null, this method call results in a NullReferenceException.
It is bad practice to return a null collection; your methods should return an empty collection instead.
There is a big difference between an empty collection and a null reference to a collection.
When you use foreach, internally, this is calling the IEnumerable's GetEnumerator() method. When the reference is null, this will raise this exception.
However, it is perfectly valid to have an empty IEnumerable or IEnumerable<T>. In this case, foreach will not "iterate" over anything (since the collection is empty), but it will also not throw, since this is a perfectly valid scenario.
Edit:
Personally, if you need to work around this, I'd recommend an extension method:
public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
{
return original ?? Enumerable.Empty<T>();
}
You can then just call:
foreach (int i in returnArray.AsNotNull())
{
// do some more stuff
}
It is being answer long back but i have tried to do this in the following way to just avoid null pointer exception and may be useful for someone using C# null check operator ?.
//fragments is a list which can be null
fragments?.ForEach((obj) =>
{
//do something with obj
});
Another extension method to work around this:
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
if(items == null) return;
foreach (var item in items) action(item);
}
Consume in several ways:
(1) with a method that accepts T:
returnArray.ForEach(Console.WriteLine);
(2) with an expression:
returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));
(3) with a multiline anonymous method
int toCompare = 10;
returnArray.ForEach(i =>
{
var thisInt = i;
var next = i++;
if(next > 10) Console.WriteLine("Match: {0}", i);
});
Because a null collection is not the same thing as an empty collection. An empty collection is a collection object with no elements; a null collection is a nonexistent object.
Here's something to try: Declare two collections of any sort. Initialize one normally so that it's empty, and assign the other the value null. Then try adding an object to both collections and see what happens.
Just write an extension method to help you out:
public static class Extensions
{
public static void ForEachWithNull<T>(this IEnumerable<T> source, Action<T> action)
{
if(source == null)
{
return;
}
foreach(var item in source)
{
action(item);
}
}
}
It is the fault of Do.Something(). The best practice here would be to return an array of size 0 (that is possible) instead of a null.
Because behind the scenes the foreach acquires an enumerator, equivalent to this:
using (IEnumerator<int> enumerator = returnArray.getEnumerator()) {
while (enumerator.MoveNext()) {
int i = enumerator.Current;
// do some more stuff
}
}
I think the explanation of why exception is thrown is very clear with the answers provided here. I just wish to complement with the way I usually work with these collections. Because, some times, I use the collection more then once and have to test if null every time. To avoid that, I do the following:
var returnArray = DoSomething() ?? Enumerable.Empty<int>();
foreach (int i in returnArray)
{
// do some more stuff
}
This way we can use the collection as much as we want without fear the exception and we don't polute the code with excessive conditional statements.
Using the null check operator ?. is also a great approach. But, in case of arrays (like the example in the question), it should be transformed into List before:
int[] returnArray = DoSomething();
returnArray?.ToList().ForEach((i) =>
{
// do some more stuff
});
SPListItem item;
DataRow dr = datatable.NewRow();
dr["ID"] = (!Object.Equals(item["ID"], null)) ? item["ID"].ToString() : string.Empty;

Checking if a list is empty with LINQ

What's the "best" (taking both speed and readability into account) way to determine if a list is empty? Even if the list is of type IEnumerable<T> and doesn't have a Count property.
Right now I'm tossing up between this:
if (myList.Count() == 0) { ... }
and this:
if (!myList.Any()) { ... }
My guess is that the second option is faster, since it'll come back with a result as soon as it sees the first item, whereas the second option (for an IEnumerable) will need to visit every item to return the count.
That being said, does the second option look as readable to you? Which would you prefer? Or can you think of a better way to test for an empty list?
Edit #lassevk's response seems to be the most logical, coupled with a bit of runtime checking to use a cached count if possible, like this:
public static bool IsEmpty<T>(this IEnumerable<T> list)
{
if (list is ICollection<T>) return ((ICollection<T>)list).Count == 0;
return !list.Any();
}
You could do this:
public static Boolean IsEmpty<T>(this IEnumerable<T> source)
{
if (source == null)
return true; // or throw an exception
return !source.Any();
}
Edit: Note that simply using the .Count method will be fast if the underlying source actually has a fast Count property. A valid optimization above would be to detect a few base types and simply use the .Count property of those, instead of the .Any() approach, but then fall back to .Any() if no guarantee can be made.
I would make one small addition to the code you seem to have settled on: check also for ICollection, as this is implemented even by some non-obsolete generic classes as well (i.e., Queue<T> and Stack<T>). I would also use as instead of is as it's more idiomatic and has been shown to be faster.
public static bool IsEmpty<T>(this IEnumerable<T> list)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
var genericCollection = list as ICollection<T>;
if (genericCollection != null)
{
return genericCollection.Count == 0;
}
var nonGenericCollection = list as ICollection;
if (nonGenericCollection != null)
{
return nonGenericCollection.Count == 0;
}
return !list.Any();
}
LINQ itself must be doing some serious optimization around the Count() method somehow.
Does this surprise you? I imagine that for IList implementations, Count simply reads the number of elements directly while Any has to query the IEnumerable.GetEnumerator method, create an instance and call MoveNext at least once.
/EDIT #Matt:
I can only assume that the Count() extension method for IEnumerable is doing something like this:
Yes, of course it does. This is what I meant. Actually, it uses ICollection instead of IList but the result is the same.
I just wrote up a quick test, try this:
IEnumerable<Object> myList = new List<Object>();
Stopwatch watch = new Stopwatch();
int x;
watch.Start();
for (var i = 0; i <= 1000000; i++)
{
if (myList.Count() == 0) x = i;
}
watch.Stop();
Stopwatch watch2 = new Stopwatch();
watch2.Start();
for (var i = 0; i <= 1000000; i++)
{
if (!myList.Any()) x = i;
}
watch2.Stop();
Console.WriteLine("myList.Count() = " + watch.ElapsedMilliseconds.ToString());
Console.WriteLine("myList.Any() = " + watch2.ElapsedMilliseconds.ToString());
Console.ReadLine();
The second is almost three times slower :)
Trying the stopwatch test again with a Stack or array or other scenarios it really depends on the type of list it seems - because they prove Count to be slower.
So I guess it depends on the type of list you're using!
(Just to point out, I put 2000+ objects in the List and count was still faster, opposite with other types)
List.Count is O(1) according to Microsoft's documentation:
http://msdn.microsoft.com/en-us/library/27b47ht3.aspx
so just use List.Count == 0 it's much faster than a query
This is because it has a data member called Count which is updated any time something is added or removed from the list, so when you call List.Count it doesn't have to iterate through every element to get it, it just returns the data member.
The second option is much quicker if you have multiple items.
Any() returns as soon as 1 item is found.
Count() has to keep going through the entire list.
For instance suppose the enumeration had 1000 items.
Any() would check the first one, then return true.
Count() would return 1000 after traversing the entire enumeration.
This is potentially worse if you use one of the predicate overrides - Count() still has to check every single item, even it there is only one match.
You get used to using the Any one - it does make sense and is readable.
One caveat - if you have a List, rather than just an IEnumerable then use that list's Count property.
#Konrad what surprises me is that in my tests, I'm passing the list into a method that accepts IEnumerable<T>, so the runtime can't optimize it by calling the Count() extension method for IList<T>.
I can only assume that the Count() extension method for IEnumerable is doing something like this:
public static int Count<T>(this IEnumerable<T> list)
{
if (list is IList<T>) return ((IList<T>)list).Count;
int i = 0;
foreach (var t in list) i++;
return i;
}
... in other words, a bit of runtime optimization for the special case of IList<T>.
/EDIT #Konrad +1 mate - you're right about it more likely being on ICollection<T>.
Ok, so what about this one?
public static bool IsEmpty<T>(this IEnumerable<T> enumerable)
{
return !enumerable.GetEnumerator().MoveNext();
}
EDIT: I've just realized that someone has sketched this solution already. It was mentioned that the Any() method will do this, but why not do it yourself? Regards
Another idea:
if(enumerable.FirstOrDefault() != null)
However I like the Any() approach more.
This was critical to get this to work with Entity Framework:
var genericCollection = list as ICollection<T>;
if (genericCollection != null)
{
//your code
}
If I check with Count() Linq executes a "SELECT COUNT(*).." in the database, but I need to check if the results contains data, I resolved to introducing FirstOrDefault() instead of Count();
Before
var cfop = from tabelaCFOPs in ERPDAOManager.GetTable<TabelaCFOPs>()
if (cfop.Count() > 0)
{
var itemCfop = cfop.First();
//....
}
After
var cfop = from tabelaCFOPs in ERPDAOManager.GetTable<TabelaCFOPs>()
var itemCfop = cfop.FirstOrDefault();
if (itemCfop != null)
{
//....
}
private bool NullTest<T>(T[] list, string attribute)
{
bool status = false;
if (list != null)
{
int flag = 0;
var property = GetProperty(list.FirstOrDefault(), attribute);
foreach (T obj in list)
{
if (property.GetValue(obj, null) == null)
flag++;
}
status = flag == 0 ? true : false;
}
return status;
}
public PropertyInfo GetProperty<T>(T obj, string str)
{
Expression<Func<T, string, PropertyInfo>> GetProperty = (TypeObj, Column) => TypeObj.GetType().GetProperty(TypeObj
.GetType().GetProperties().ToList()
.Find(property => property.Name
.ToLower() == Column
.ToLower()).Name.ToString());
return GetProperty.Compile()(obj, str);
}
Here's my implementation of Dan Tao's answer, allowing for a predicate:
public static bool IsEmpty<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null) throw new ArgumentNullException();
if (IsCollectionAndEmpty(source)) return true;
return !source.Any(predicate);
}
public static bool IsEmpty<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw new ArgumentNullException();
if (IsCollectionAndEmpty(source)) return true;
return !source.Any();
}
private static bool IsCollectionAndEmpty<TSource>(IEnumerable<TSource> source)
{
var genericCollection = source as ICollection<TSource>;
if (genericCollection != null) return genericCollection.Count == 0;
var nonGenericCollection = source as ICollection;
if (nonGenericCollection != null) return nonGenericCollection.Count == 0;
return false;
}
List<T> li = new List<T>();
(li.First().DefaultValue.HasValue) ? string.Format("{0:yyyy/MM/dd}", sender.First().DefaultValue.Value) : string.Empty;
myList.ToList().Count == 0. That's all
This extension method works for me:
public static bool IsEmpty<T>(this IEnumerable<T> enumerable)
{
try
{
enumerable.First();
return false;
}
catch (InvalidOperationException)
{
return true;
}
}

Categories

Resources