Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to empty IEnumerable list? [closed]

Tags:

c#

asp.net-mvc

I need to empty IEnumerable list i tried many things like null and none of them worked

this how my model looks like

public class NewsViewModel
{
    public NewsViewModel()
    {
        this.Categories = new List<Category>();
    }

    public int NewsId { get; set; }
    public string NewsTitle { get; set; }
    public string NewsBody { get; set; }

    public IEnumerable<Category> Categories { get; set; }
}

if (!string.IsNullOrEmpty(SelectedCategoriesIds))
{
    List<Category> stringList = new List<Category>();
    stringList.AddRange(SelectedCategoriesIds.Split(',').Select(i => new Category() { CategoryId = int.Parse(i) }));
    model.Categories = stringList.AsEnumerable();
}
else
{
    model.Categories = null;
}

How to make model.Categories empty ?

like image 269
Lucy Avatar asked Jul 20 '16 21:07

Lucy


People also ask

How do I empty an IEnumerable list?

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.

How do I return an empty enumerable?

#Returning an Empty Collection: Enumerable. Empty<T> Empty<T> method returns an empty enumerable which doesn't yield any values when being enumerated. Enumerable. Empty<T> comes in very handy when you want to pass an empty to collection to a method accepting a parameter of type IEnumerable<T> .

What is default IEnumerable?

default Keyword: will be null for reference types and zero for value types. IEnumerable is not value type, so result will be null.

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

Use Enumerable.Empty<T>().

model.Categories = Enumerable.Empty<Category>();

The Empty() method caches an empty sequence of type TResult. When the object it returns is enumerated, it yields no elements.

An enumerable sequence with no elements is different from null. If you return null for IEnumerable<T> and then attempt to enumerate it, you will receive a NullReferenceException.

On the other hand, if you return Enumerable.Empty<T>() and attempt to enumerate it, the code will execute just fine without the need for a null check, since there are no elements to enumerate.

It is worth noting that Enumerable.Empty<T>() is also more efficient than returning new List<T>() since a new list object does not need to be allocated.

You cannot use .Clear() in this instance because your IEnumerable<T> is a projectable sequence that is not materialized until enumerated. There isn't anything to clear yet.

Finally, as spender mentioned below, this will only update this particular reference. If anything else also is holding a reference to your IEnumerable<T>, it would not reflect the change unless you specifically passed in model.Categories via ref.

Alternatively, you can cast to List<Category> and call .Clear(), which would clear the underlying collection, updating all references. However, you will also need to perform an explicit null check when doing so, as mentioned in other answers. Note however, that this is also a very aggressive action. You are not updating only this instance, but all instances which may or may not have side effects. You need to determine which is more appropriate based on intent and needs.

like image 196
David L Avatar answered Dec 10 '22 02:12

David L


If assigning a new value

You can also use an empty array for this

  if (!string.IsNullOrEmpty(SelectedCategoriesIds))
  {
           List<Category> stringList = new List<Category>();
           stringList.AddRange(
                SelectedCategoriesIds.Split(',')
                     .Select(i => new Category() { CategoryId = int.Parse(i) }));
            model.Categories = stringList.AsEnumerable();
 }
 else
 {
      //set the property to an empty arrary
      model.Categories = new Category[]{};
 }

This is less efficient than @DavidL's answer but is an alternative way to create an empty enumerable

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.

 public class NewsViewModel
 {
    public NewsViewModel()
    {
        this.Categories = new List<Category>();
    }
    public int NewsId { get; set; }
    public string NewsTitle { get; set; }
    public string NewsBody { get; set; }

    public IList<Category> Categories { get; set; }

}

Then in your if statement you can use clear

else
 {
      //Now clear is available
      model.Categories.Clear();
 }
like image 44
konkked Avatar answered Dec 10 '22 00:12

konkked