【问题标题】:ICollection - Get single valueICollection - 获取单个值
【发布时间】:2010-09-26 16:09:30
【问题描述】:

从 ICollection 中获取值的最佳方法是什么? 除此之外,我们知道 Collection 是空的。

【问题讨论】:

    标签: c# .net icollection


    【解决方案1】:

    最简单的方法是:

    foreach(object o in collection) {
      return o;
    }
    

    但如果它实际上是一个泛型集合,这并不是特别有效,因为 IEnumerator 实现了 IDisposable,因此编译器必须放入 try/finally,并在 finally 块中调用 Dispose()。

    如果它是非泛型集合,或者您知道泛型集合在其 Dispose() 方法中没有实现任何内容,则可以使用以下内容:

    IEnumerator en = collection.GetEnumerator();
    en.MoveNext();
    return en.Current;
    

    如果你知道是否可以实现 IList,你可以这样做:

    IList iList = collection as IList;
    if (iList != null) {
      // Implements IList, so can use indexer
      return iList[0];
    }
    // Use the slower way
    foreach (object o in collection) {
      return o;
    }
    

    同样,如果它可能是您自己定义的某种类型的具有某种索引访问的,您可以使用相同的技术。

    【讨论】:

      【解决方案2】:

      没有泛型,因为ICollection 实现了IEnumerable,您可以像示例 1 中那样做。使用泛型,您只需像示例 2 那样做:

      List<string> l = new List<string>();
      l.Add("astring");
      
      ICollection col1 = (ICollection)l;
      ICollection<string> col2 = (ICollection<string>)l;
      
      //example 1
      IEnumerator e1 = col1.GetEnumerator();
      if (e1.MoveNext())
          Console.WriteLine(e1.Current);
      
      //example 2
      if (col2.Count != 0)
          Console.WriteLine(col2.Single());
      

      【讨论】:

      【解决方案3】:

      您可以为此使用 LINQ:。

      var foo = myICollection.OfType<YourType>().FirstOrDefault();
      // or use a query
      var bar = (from x in myICollection.OfType<YourType>() where x.SomeProperty == someValue select x)
         .FirstOrDefault();
      

      【讨论】:

      • FirstOrDefault 在 ICollection 或 IEnumerable(非泛型)上定义?在哪里?什么会起作用:myICollection.OfType().FirstOrDefault();
      • 这是正确的答案。 First 和 FirstOrDefault 甚至尽可能在内部使用 IList 优化。
      • 我正在寻找 FirstOrDefault() 但智能感知告诉我不可能......直到我添加了 System.Linq 的使用。因此,在执行任何此操作之前,请检查您在代码开头添加的内容:using System.Linq;
      【解决方案4】:
      collection.ToArray()[i]
      

      这种方式速度慢,但使用起来非常简单。

      【讨论】:

      • 复制整个集合只是为了得到一个值。
      • “除此之外,我们知道集合是空的。”。为简单起见,以上将有其用途。虽然不是最好的通用答案,因为它会被滥用。
      【解决方案5】:

      如果你知道你的收藏只有一项,应该只有一项,你可以使用 Linq 扩展方法Single()

      这会将ICollection&lt;T&gt; 转换为包含该集合的单个项目的T 对象。如果集合的长度为 0 或大于 1,则会抛出 InvalidOperationException

      【讨论】:

        猜你喜欢
        • 2017-10-15
        • 1970-01-01
        • 2014-04-16
        • 2019-02-04
        • 2021-11-08
        • 2015-02-15
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        相关资源
        最近更新 更多