【问题标题】:How to initialize IEnumerable<Object> that be empty and allow to Concat to it?如何初始化为空的 IEnumerable<Object> 并允许 Concat 到它?
【发布时间】:2013-07-23 18:02:44
【问题描述】:

我尝试使用此代码将b 添加到books:

IEnumerable<Book> books =null;
foreach (Book b in context.Books.AsEnumerable())
    if (someConditions)
       books = books.Concat(new[] {b});

但是在最后一行代码给了我这个错误:

System.ArgumentNullException:值不能为空。 参数名称:first

似乎null Collection 无法连接。我使用 EF,那么我应该如何初始化我的 Collection 里面没有任何东西,我可以连接到它?

【问题讨论】:

  • 你不能在 null 上运行方法 Concat
  • IEnumerable books = new List();
  • IEnumerable&lt;Book&gt; books = Enumerable.Empty&lt;Book&gt;();
  • @VyacheslavVolkov 这应该是一个答案。
  • 其他人已经回答了您的问题。但是,通过连接大量Book[] 类型的长度为1 的数组来创建IEnumerable&lt;Book&gt; 仍然非常低效,而且有些丑陋。考虑使用 Linq Where 过滤您的书籍,就像在 @Damith 的评论中一样,或者可能重写以使用循环中的 yield return b;(将此循环提取到一个新方法,一个 iterator 块)。

标签: c# linq linq-to-entities concatenation argumentnullexception


【解决方案1】:

这就是你想要做的:

IEnumerable<Book> books = Enumerable.Empty<Book>();
books = books.Concat(context.Books.AsEnumerable().Where(b => someCondition));

如果您想从 null 开始,也可以这样做:

IEnumerable<Book> books = null;
var moreBooks = context.Books.AsEnumerable().Where(b => someCondition);
books = books == null ? moreBooks : books.Concat(moreBooks);

...虽然我对您为什么想要/需要以这种方式做事有几个问题。

【讨论】:

    【解决方案2】:

    你想要做的就是按照某些标准过滤你的上下文。书籍。

    IEnumerable<Book> books = context.Books.Where(b => someConditions);
    

    如果您仍然需要空的 IEnumerable,您可以调用 Enumerable.Empty():

    IEnumerable<Book> books = Enumerable.Empty<Book>();
    

    【讨论】:

      【解决方案3】:

      我个人会选择:

      IEnumerable<Book> books = new Book[0];
      

      而不是使用列表。

      【讨论】:

      • 虽然我仍然会使用 Enumerable.Empty&lt;T&gt; 而不是这个,因为它避免创建新的数组实例,但这仍然比根据接受的答案创建 List&lt;T&gt; 更好,因为 .网络缓存零长度数组的枚举器!
      • @AnorZaken 我同意Enumberable.Empty&lt;T&gt; 会更好(因为它更具描述性),但请注意它仍然(懒惰地)创建一个空数组。
      • 是的,但它只对每个类型 T 执行一次,使用类型系统和 JIT 使其惰性和缓存(通用静态只读字段)。所以Enumerable.Empty 仍然名列前茅。 (我们不知道那条线会被调用多少次——也许每秒 1000 次,只有 OP 知道。)
      【解决方案4】:

      您需要将书籍创建为像 List 一样的 IEnumerable 空对象,但需要记住在循环之后调用书籍上的 ToList()。例如:

              IEnumerable<int> books = new List<int>();
              IEnumerable<int> books2 = new int[] { 1, 2, 3, 4 };
      
      
              foreach (int b in books2)
                  if (b > 2)
                      books = (new[] { b }).Concat(books);
      
              books = books.ToList();
      

      【讨论】:

      • 或者像上面提到的Vyacheslav Volkov一样使用Enumerable.Empty()。
      【解决方案5】:
      IEnumerable<Book> books = new List<Book>();
      

      【讨论】:

        猜你喜欢
        • 2021-12-25
        • 2021-08-03
        • 2020-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-22
        相关资源
        最近更新 更多