将IEnumerable转换为IList返回null

3
我正在调用一个代码仓库,该代码返回一个
IEnumerable<MyEntity>

当我试图将结果实例化时,只有在结果上执行.ToList()才有效,但如果我尝试一个

就不行了。
as IList<MyEntity>

它返回null。它们不应该产生相同的结果吗?

5
ToList 是一个方法,它枚举整个序列并将每个项添加到新的列表中,而 as IList<T> 只是将可枚举对象强制转换为所需类型,这当然会失败,因为它不是一个 IList<T> 而只是一个查询。 - Tim Schmelter
1
请注意,as运算符仅执行引用转换、可空转换和装箱转换。as运算符无法执行其他转换,例如用户定义的转换,应改为使用强制转换表达式来执行。 - mbadeveloper
虽然 ToList 将源转换为 List,因此可以检索数据,但如果源不是 IList,则 IList 将失败。如果要实现结果的物化,应调用任何具有 To[whatever] 的方法以强制检索。 - Cleptus
这些评论和大部分答案都是正确的;你实际使用的 IEnumerable<MyEntity>Type 是什么,HashSet 还是 DbSet?尝试使用 as ISet<MyEntity> 替换 as IList<MyEntity> - Brett Caswell
2个回答

4

.ToList()将你的IEnumerable转换为List
as IList("尝试")将你的IEnumerable强制转换为IList

有可能你的IEnumerable根本不是IList,一个简单的例子可能是class Dictionary

public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
    ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
    IEnumerable, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>, 
    IReadOnlyCollection<KeyValuePair<TKey, TValue>>, ISerializable, 
    IDeserializationCallback

我们可以看到以上接口都不是IList
编辑:感谢@patrick-hofman的评论,重要的是要检查整个实现链以确保该类不是IList(在这种情况下当然可以)。

话虽如此,从IList的签名中我们可以看到:

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable

IListIEnumerable,但IEnumerable不是IList


这是一个简单的例子,说明为什么这样的强制转换可能不起作用。 - Yan
2
除非您显示字典的每个接口定义,否则您的代码什么也不表示。从那段代码中,您怎么能知道IDictionary<TKey, TValue>没有实现IList<T>呢? - Patrick Hofman
1
你说得对,仅有的签名本身并不能确定它不是一个IList。我会编辑答案来强调这一点。谢谢。 - Yan
1
@Yan 我认为答案如果没有字典签名可能会更好,因为搜索这个问题的人很可能处于一个水平,一个实现10个接口的2个参数泛型签名会让他们感到困惑而不是帮助他们。简单地说,并不是所有的集合都实现了IList,也不是所有的IEnumerable都是实体化的集合,这样会更有帮助。 - Ronan Thibaudau

4
那么您的可枚举对象没有实现>类型,例如List或类似类型。as只是在实例是该类型时将变量强制转换为指定类型。它不进行任何转换。
ToList()实际上强制创建一个新的List,因此在这里创建的新实例确实实现了IList。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接