Net*_*age 1 c# linq collections
如果我有LINQ创建的匿名类型
var ans = from r in someList where someCondition(r) select new { r.a, r.b };
Run Code Online (Sandbox Code Playgroud)
创建空匹配集合的最佳方法是什么,以便我可以将元素移动到新集合:
var newans = ?
foreach (r in ans) { if (complicated(r)) newans.Add(r); }
Run Code Online (Sandbox Code Playgroud)
有没有办法使用Enumerable.Empty <>()?
我不会使用ans.Where(x => false).ToList()这些迭代的版本来覆盖你不需要的所有元素; ans.Take(0).ToList()稍微好一点,因为当你查询内存中的序列(LINQ to Objects)时,这个实际上并没有迭代整个列表.
如果您正在使用LINQ to SomethingElse,事情是有点问题的,因为它实际上可能像执行的东西SELECT TOP(0) * FROM ...或SELECT * FROM ... WHERE 1 = 0.不好.
所以以下帮助方法将帮助您:
public static class AnonymousTypeExtensions
{
public static List<T> ToEmptyList<T>(this IEnumerable<T> source)
{
return new List<T>();
}
}
var newans = ans.ToEmptyList();
Run Code Online (Sandbox Code Playgroud)
话虽如此,如果你唯一的愿望是将一些元素复制ans到一个新的列表中,你最好还是有
var newans = (from a in ans where isComplicated(a) select a).ToList();
Run Code Online (Sandbox Code Playgroud)
要么
var newans = ans.Where(a => isComplicated(a)).ToList();
Run Code Online (Sandbox Code Playgroud)
如果你不需要一个实际的List<T>,一个IEnumerable<T>就够了,你可能ToList完全省略了.请注意,每当你对这样一个可以说明的事物进行预告时,你Where(a => isComplicated(a))都会被一次又一次地执行.调用ToList确保您只执行一次.
如果你不想这样做List<T>,但更一般的是,事情变得复杂得多.例如,该方法是否应返回ans变量的静态类型或其运行时类型?此外,除了盲目呼叫之外,没有诸如许多集合的"默认"版本之类的东西new C().但这不会普遍起作用.它不可能调用new ReadOnlyCollection<T>(),因为它不存在(并且集合将被密封,因此无法填充).如果您使用的是HasSet,那么您是否应该使用原始的比较器作为空副本而不是默认的比较器?
但是,对于最简单的情况,您可以尝试:
public static class CollectionExtensions
{
public static TCollection AsEmpty<TCollection>(this TCollection source)
where TCollection : ICollection, new()
{
return new TCollection();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是一个编译时解决方案,它返回变量类型的默认集合.如果可能的话.例如,ans = from r in somesource select new { ... }将具有静态类型IEnumerable<...>.这里没有要创建的默认实例.此外,返回的运行时类型select对System.Core.dll是私有的,没有默认构造函数,并且无论如何都是只读游标类型.
所以我对这一点的看法是:不要去那里.不要试图过度概括,坚持像ToEmptyList这样的简单解决方案,甚至更好,坚持使用简单的LINQ方法链接.
| 归档时间: |
|
| 查看次数: |
3070 次 |
| 最近记录: |