1

I started working on a project and I have noticed that ToList() gets called multiple times and I think it is not really necessary and redundant.

The first ToList() is at the data layer where the call goes to database and gets the data.

    public IEnumerable<Company> GetCompanies()
    {
        return DbContext.Companies.ToList();
    }

Then at the controller I can see another call as ToList()

        public ActionResult Index()
    {
        var companies = _companyService.GetCompanies().ToList();
        return View(companies);
    }

I believe that calling ToList() in the controller is redundant. But I just wonder whether it has any impact on performance or the language itself recognizes automatically that the result is actually is already list and ignores the second call?

Update

The other question asks if there is an impact calling ToList(). However, I wonder whether there is an impact calling the ToList() multiple times for the same list of objects. As someone mentioned that that should be "hopefully ignored".

akd
  • 6,538
  • 16
  • 70
  • 112
  • 4
    It is poor design. Your methods should return as specific type as possible in the signature. The method arguments should be as generic as possible. In the above case the signature of `GetCompanies` should be changed to return `List` – Igor Oct 23 '17 at 10:14
  • 2
    Use a profiler to check *if* a call has any impact. We can´t know as we don´t know where your data comes from. Is it a database? Some service? A file? This has a high influence on wheather the results will be cached or not. But most important is: what is `DbContext.Companies`? – MakePeaceGreatAgain Oct 23 '17 at 10:14
  • 1
    Hopefully the redundant call is ignored since `ToList()` on a list won't make sense – Rahul Oct 23 '17 at 10:14
  • 1
    @Rahul, `ToList()` on an `List` **does** perfectly make sense, since this is not casting and not a type conversion method. This method creates a `List` using the provided `IEnumerable` as items source. – dymanoid Oct 23 '17 at 10:17
  • 1
    @Igor "Your methods should return as specific type as possible in the signature." I don´t agree, a method should return what the caller may need. There´s no need to force a method to return a list, if we only want to iterate the result. However if we want to add some data to the result you surely want a list. – MakePeaceGreatAgain Oct 23 '17 at 10:18
  • @HimBromBeere - I am not stating that all methods should return a List but if a method returns Type `C` and `C` derives from `B` and `B` from `A` then the return type of the method should be declared as `C` and not `B` or `A`. There are exceptions, like when abstracting return types (returning interfaces instead of concrete types in the signature) but when dealing with standard built in .net types (`List` included) this is *almost* always preferred. – Igor Oct 23 '17 at 10:22
  • not sure why this is marked as duplicated? @PatrickHofman. The other question is just asking whether there is performance impact calling the ToList(). I wonder whether there is an impact calling it multiple times. – akd Oct 23 '17 at 10:25
  • And I am confused with the answers given here. – akd Oct 23 '17 at 10:25
  • 2
    Which is the same. Impact once is impact multiple times. – Patrick Hofman Oct 23 '17 at 10:26
  • *This constructor must make a copy of the array (more generally IEnumerable), otherwise future modifications of the original array will change on the source T[] also which wouldn't be desirable generally.* – Patrick Hofman Oct 23 '17 at 10:26
  • 2
    @akd well is there is perfomance impact calling it once - there is more perfomance impact calling it multiple times, not? – Evk Oct 23 '17 at 10:26
  • @Evk just thinking that the language might just ignore the second call as it is redundant. Similar the SQL query optimizer that analyse your query. – akd Oct 23 '17 at 10:44
  • 2
    @akd yes but the accepted answer in duplicated question provides details of `ToList` implementation where you can see that even if you call `ToList` on `List` - it will still copy it to the new list. – Evk Oct 23 '17 at 10:45
  • @HimBromBeere it is database. retrieving data from database. – akd Oct 23 '17 at 10:46
  • @Evk thanks I missed that bit. – akd Oct 23 '17 at 10:48

1 Answers1

6

Yes, there is a performance impact. Even if the underlying IEnumerable<T> is already a List<T> a call to ToList will cause new list to be created (so list != list.ToList()). Depending on the size of the original list, this may have serious performance implications

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357