Is AsList() better than ToList() with IDbConnection.Query() which returns IEnumerable?

后端 未结 2 455
遥遥无期
遥遥无期 2021-01-02 02:50

I read this answer from Marc Gravell (@MarcGravell): https://stackoverflow.com/a/47790712/5779732

The last line says:

As a minor optimization

2条回答
  •  天命终不由人
    2021-01-02 03:33

    This extension is a custom dapper extension which does an additional check before calling ToList. Source:

    public static List AsList(this IEnumerable source) 
        => (source == null || source is List) ? (List)source : source.ToList();
    
    • ToList always creates a new List instance and fills it with the given items
    • AsList checks if the sequence is already a List, then it will just cast it

    Of course this approach can be more efficient because casting something is much less work than creating and filling something new. So it's completely different.

    This is kind of opinion based, but i find this dangerous. Someone might overlook the AsList and reads ToList or just don't know the difference. It's dangerous if someone changes the code later.

    So for example a method that takes IEnumerable which uses AsList:

    public static List GetResult(IEnumerable seq)
    {
        if(some condition here)
        {
            seq = seq.Where(some predicate here);
        }
        return seq.AsList()
    }
    

    Now code called this method with a list:

    IEnumerable sequence = (gets a list from somewhere)
    List userList = GetResult(sequence);
    

    Later someone decides that an array is more appropriate here:

    IEnumerable sequence = (gets an array from somewhere)
    List userList = GetResult(sequence);
    

    This doesn't really hurt until now. Now a new List is initialized and filled because the source is not a list and can't be casted. So it's just less efficient. But if the logic also relied on the list being the same reference, this won't work anymore.

    if(userList == seq)
    {
        // do something
    }
    

    This is always false once the array is used . So the code was broken silently.

    To cut a long story short: i don't like the AsList method. You can always check the type yourself.

提交回复
热议问题