Afzaal Ahmad Zeeshan
Afzaal Ahmad Zeeshan

Reputation: 15860

List Count vs List null condition, change results

I am having a program which would first iterate through the File data and then would convert the (JSON) data to an Object. Object depends on the File that I'm trying to access the data from. That's pretty much unrelated to the question I'm going to ask.

When I complete the project, and I was ready to send it to my friends, I found that there was one thing I didn't understand regarding the List<>s of C#.

Here is the code I'm using:

// File is not empty!
string file = File.ReadAllText(new MainWindow().getFileName("events"));
List<Event> events = JsonConvert.DeserializeObject<List<Event>>(file);

After this, I'm trying to populate the ListView by each event I'm having, or I'm trying to populate a TextBlock with a text saying, there is no event create one now.

I'm using this condition.

if(events != null) {
   // goes well
} else {
   // populate the code text view 
}

In this code, the else block doesn't get triggered. If there are events, it populates the list otherwise it just skips the textView update code.

enter image description here

But, if I use this code instead,

if(events.Count != 0) {
   // listview code..
} else { 
   // populate text view
}

Using this, I can populate the textView and I can see the error message in the Page.

enter image description here

I have added the code image, and the working example for that. Hope someone can tell me the difference

(List.Count == 0) || (List == null) 
/* irrelevant piece of code, I'm trying to ask, should I use 
 * List Count == 0 OR List is equal to null */

Upvotes: 4

Views: 27798

Answers (2)

isaias-b
isaias-b

Reputation: 2289

For some list variable

List<SomeType> list = // initialization

it might happen that the variable list might not get initialized correctly and no object is set up. In such case the value of the variable is null. Though

  • list == null evaluates to true and
  • list.Count throws a NullReferenceException

On the other hand, if a list could be obtained. Then you will be able to call Count on the list which tells the number of elements within that list. Though

  • list == null evaluates to false and
  • list.Count == 0 evaluates to true if the list contains no elements and false if it contains at least one elements.

To be on the safe side (not only for programming paranoids) it is good to check wether a variable can be null or not. By this i mean check the documentation of the API you're getting the object from.

If you know it may be possibly null you will need to address this situation by checking list == null first. If you don't know you probably should check for null. I would suggest to check for null and if so - assign an empty list to your list.

List<SomeType> list = // initialization
list = (list == null) ? new List<SomeType>() : list;

if(list.Count == 0) 
  // do whatever you like here
else
  // or even here

Alternatively put the initialization into another method which only is dedicated to retrieve your list. If it somehow fails it returns an empty list. This way you can handle all the following code by checking only one condition. The condition if the list.Count == 0.

List<SomeType> RetrieveList()
{
    List<SomeType> list = // initialization possibly null
    return (list == null) ? new List<SomeType>() : list;
}

Hope this helps

Upvotes: 8

Eugene Podskal
Eugene Podskal

Reputation: 10401

The documentation doesn't say anything about the actual return value of JsonConvert.DeserializeObject .

But it seems that List<Event> events = JsonConvert.DeserializeObject<List<Event>>(file); never sets events to null, that's why your code

if(events != null) {
   // goes well
} else {
   // populate the code text view 
}

doesn't do what it is supposed to do.

But it(JsonConvert) can return an empty list. That's why these code does what it is supposed to accomplish:

if(events.Count != 0) {
   // listview code..
} else { 
   // populate text view
}

because in case of the unsuccessful parsing JsonConvert.DeserializeObject returns the empty List.

Well, (List.Count == 0) || (List == null) should be written as (List == null) || (List .Count == 0) because if list somehow will become null you will have an unexpected NulReferenceException. For more details read Execution order of conditions in C# If statement

It is possible that the behaviour of JsonConvert could change, so it'd be better to use

if ((events == null) || (events.Count == 0)) {
   // Error handling - populate text view
} else { 
   // Everything is ok - listview code..
}

Upvotes: 4

Related Questions