如何在不创建新列表的情况下检索IEnumerable的基础列表?

时间:2019-04-17 15:15:53

标签: c# ienumerable

使用IEnumerable时,我试图避免多个枚举。我知道我可以只使用LINQ的.ToList()并完成它,但这可能会造成很多不必要的列表创建。我想:

  1. 检查并查看基础类型是否为List,如果是,则返回该实例,否则
  2. .ToList(),并返回新列表

我的想法是使用类似于:

public void Fee()
{
    var list = new List<string>(); // I want to retrieve this instance in Foo
    Foo(list);
}

public void Foo(IEnumerable<T> enumerable)
{  
    var list = enumerable as List<T> ?? enumerable.ToList();
    // do stuff with original list 
}

...但是在文档中似乎发现as运算符只是执行强制转换,这将创建一个新的List而不是返回基础列表,不是吗?

如果是这样,我如何检索基础列表而不是创建一个新列表?

2 个答案:

答案 0 :(得分:3)

as operator不会创建新列表。如果类型兼容,它只会检查类型并执行强制转换。

帖子中的代码在逻辑上是正确的,并且与实现了LINQ方法相匹配(例如,请参见Enumerable.Count的源,后者转换为ICollection,以查看其是否可以跳过项的枚举)。 / p>

请注意,强制转换正确的列表或列表的其中一个接口是通用的很重要-如果必须使用非通用版本,IList将可以正常工作。请注意以下事实:List<T>不是协/逆变数,并且类型必须完全匹配,而在covariant IEnumerable<out T>的情况下,如果{{ 1}}通过。

答案 1 :(得分:0)

也许您想这样做:

public void Fee()
{
    var list = new List<string>(); // I want to retrieve this instance in Foo
    Foo(list);
}

public void Foo<T>(IEnumerable<T> enumerable)
{
    List<T> list = enumerable as List<T> ?? enumerable.ToList();
    // do stuff with original list 
}