Freeman
Freeman

Reputation: 5801

Which IEnumerable To a List way is better?

I am wondering about the following fact. I have a data repository that returns all my data of IEnumerable<Customer>.

In my business logic sometimes I need lists so I can add stuff for example.

When I retrieve the IEnumerable<Customer> I have 2 options to get a list from it.

Either using the Linq extension method .ToList() or cast it (I think its not a conversion) like this (List<Customer>)IEnumerable<Customer>.

Must mention that I don't use the list for iterations so I don't need a new copy of my enumeration each time. In this case is it true that in my simple case I must use the cast method instead of .ToList (which creates a new copy) ?

// use simple cast?
List<Customer> customers = (List<Customers>)DataSource.GetCustomers(); 

// or if i use this i get a bit of performance loss?
List<Customer> customers = DataSource.GetCustomers().ToList(); 

Upvotes: 2

Views: 375

Answers (5)

digEmAll
digEmAll

Reputation: 57220

I'd go with the ToList(), since the method returns an IEnumerable<Customer> and you cannot be sure of the inner implementation.

Maybe now GetCustomers() returns a List<> masked by an IEnumerable<>, but what if in the future the inner implementation changes ?

EDIT :

List<Customer> implements the interface IEnumerable<Customer>, as well as an array like Customer[] or a LinkedList<Customer>. Hence, when you receive an object of type IEnumerable<WhateverClass> you cannot be sure it is a List<Customer> and, of course, the cast works only if the type you're casting to is the same behind the interface, otherwise you will receive an exception.

Using ToList(), as you correctly said, you create a new object containing the elements of the IEnumerable<>, but at least you can safely iterate/modify that object without any exception.

The methods returns IEnumerable<T> because in this way it is not bound to any specific collection implementation, and in the future it can switch for example from list to array or whatever without changing the method signature...

Upvotes: 5

ThunderGr
ThunderGr

Reputation: 2367

You can go with the cast by using a condition, to safeguard against future implementation changes. Something like

List<Customer> customers = null;
try
{
     customers = (List<Customers>)DataSource.GetCustomers();
}
catch
{
    customers = DataSource.GetCustomers().ToList();
}

This way, you can avoid copying the list, as long as the IEnumerable is a list, but your code will keep working if, for some reason, in the future the inner implementation changes.

Upvotes: 1

Maxim
Maxim

Reputation: 7348

It depends. If the size is small I'd go with the .ToList(), but you have to understand that this will do a copy of the list.

If it's big or you're doing it a lot (and it creates performance penalty) you can check if the returned object from .GetCustomers() is a list if yes - cast, else create a copy with .ToList().

Upvotes: 2

Arjan Einbu
Arjan Einbu

Reputation: 13692

The whole point of your repository returning an IEnumerable is that it isn't guaranteed to actually be a list. (It may be now, but the use of IEnumerable allows the implementation to be changed later).

Either go with the .ToList() method, or make the repository return a List or IList instead.

Upvotes: 0

Stilgar
Stilgar

Reputation: 23591

I would recommend using .ToList(). It will perform worse but if you cast you are using information about the implementation details of the API and you are making unwarranted assumptions. Tomorrow someone will change the IEnumerable to something that is not a list and your code will start throwing exceptions.

Upvotes: 1

Related Questions