如何在不创建新列表的情况下检索 IEnumerable 的基础列表?
How Can I Retrieve the Underlying List of an IEnumerable Without Creating a New List?
使用 IEnumerable
时,我试图避免多次枚举。我知道我可以只使用 LINQ 的 .ToList()
并完成它,但这可能是很多不必要的列表创建。我想:
- 检查并查看基础类型是否为 List,如果是 return 那个实例,否则
.ToList()
它和 return 新列表
我的想法是使用类似于:
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
运算符只是执行一个转换,这将创建一个新列表而不是 returning 底层列表,不是吗?
如果是这样,我如何才能检索基础列表而不是创建新列表?
as
operator 不会创建新列表。它只检查类型并在类型兼容时执行转换。
post 中的代码在逻辑上是正确的,并且与实现的 LINQ 方法的数量相匹配(例如,请参阅 Enumerable.Count
的源代码,它转换为 ICollection
以查看它是否可以跳过项目枚举)。
请注意,重要的是转换为正确的列表通用版本或它的接口之一 - 如果您必须使用非通用版本,IList
会起作用。请注意 List<T>
不是 co/contra-variant 并且类型必须完全匹配,这与 covariant IEnumerable<out T>
的情况不同,您可以将参数转换为 IEnumerable<TBase>
if IEnumerable<TDerived>
通过。
也许您想这样做:
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
}
使用 IEnumerable
时,我试图避免多次枚举。我知道我可以只使用 LINQ 的 .ToList()
并完成它,但这可能是很多不必要的列表创建。我想:
- 检查并查看基础类型是否为 List,如果是 return 那个实例,否则
.ToList()
它和 return 新列表
我的想法是使用类似于:
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
运算符只是执行一个转换,这将创建一个新列表而不是 returning 底层列表,不是吗?
如果是这样,我如何才能检索基础列表而不是创建新列表?
as
operator 不会创建新列表。它只检查类型并在类型兼容时执行转换。
post 中的代码在逻辑上是正确的,并且与实现的 LINQ 方法的数量相匹配(例如,请参阅 Enumerable.Count
的源代码,它转换为 ICollection
以查看它是否可以跳过项目枚举)。
请注意,重要的是转换为正确的列表通用版本或它的接口之一 - 如果您必须使用非通用版本,IList
会起作用。请注意 List<T>
不是 co/contra-variant 并且类型必须完全匹配,这与 covariant IEnumerable<out T>
的情况不同,您可以将参数转换为 IEnumerable<TBase>
if IEnumerable<TDerived>
通过。
也许您想这样做:
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
}