【问题标题】:difference between IEnumerable<T>.Reverse & List<T>.Reverse [duplicate]IEnumerable<T>.Reverse 和 List<T>.Reverse 之间的区别 [重复]
【发布时间】:2015-05-15 15:23:31
【问题描述】:

为什么IEnumerable&lt;T&gt;.Reverse() 会返回带有原始集合的反转集合,而List&lt;T&gt; 会反转原始集合本身?这让我有些困惑,因为 List&lt;T&gt; 继承自 IEnumerable&lt;T&gt;

【问题讨论】:

  • IEnumerable&lt;T&gt; 是一个接口,List&lt;T&gt; 不继承它,它实现它。这是一个巨大的差异。

标签: c# generic-collections


【解决方案1】:

从概念上讲,这可能是因为IEnumerable 在您想要表示不可变的项目集合时使用。也就是说,您只想读取列表中的项目,而不是添加/插入/删除或以其他方式更改集合。在这个数据视图中,以不同的顺序返回一个新的IEnumerable 是预期的结果。当您使用 List 时,您希望能够添加/插入/删除或以其他方式改变集合,因此在该上下文中需要更改原始列表顺序的 Reverse 方法。

正如其他人所说,IEnumerable 是一个接口,List 是一个类。 List 实现 IEnumerable

所以,

 IEnumerable<String> names = new List<String>();
 var reversedNames = names.Reverse();

为您提供第二个列表,相反。 鉴于,

 List<String> names = new List<String>();
 names.Reverse(); 

反转您的原始列表。我希望这是有道理的。

【讨论】:

    【解决方案2】:

    因为它们是两种不同的方法。

    List&lt;T&gt;.ReverseList&lt;T&gt; 上的实例方法。这会修改列表。

    Enumerable.Reverse&lt;T&gt;IEnumerable&lt;T&gt; 的扩展方法。这将创建一个以相反顺序枚举源序列的新序列。

    您可以在List&lt;T&gt; 上通过作为静态方法调用来使用后者:

    var list = new List<string>{"1","2"};
    var reversed = Enumerable.Reverse(list)
    

    或者通过转换为IEnumerable&lt;T&gt;:

    IEnumerable<string> list = new List<string>{"1","2"};
    var reversed = list.Reverse();
    

    在这两种情况下,list 保持不变,reversed 在枚举时返回 {"2","1"}

    【讨论】:

    • 我添加了一个扩展方法“Reversed”,它只包装了 Ienumerable.Reverse - 通常你想要不变性,现在你可以直接调用它而无需任何转换或其他样板代码。
    【解决方案3】:

    IEnumerable&lt;T&gt; 上的Reverse 是 Linq 的一部分,并作为扩展方法 (Enumerable.Reverse&lt;T&gt;) 添加。它是在为List&lt;T&gt; 实施Reverse 之后添加的。

    IEnumerable&lt;T&gt; 也不是对象的集合。它只是告诉消费者如何获得这些物品。

    【讨论】:

    • 看起来只有这个答案可以解释为什么“它是在为List&lt;T&gt;实现Reverse之后添加的”
    【解决方案4】:

    这些是不同的方法,请记住。本质上是不同的,只有一个名字。

    void List.Reverse 仅是 List 实例的一个方法,它可以对列表或其一部分进行反转。

    IEnumerable Enumerable.Reverse 是一种扩展方法(顺便说一句,IList 也有它!)创建一个新的可枚举,顺序颠倒。

    【讨论】:

      【解决方案5】:

      没有IEnumerable&lt;T&gt;.Reverse()这样的东西,它是Enumerable.Reverse&lt;T&gt;(this IEnumerable&lt;T&gt;),它是Linq的扩展方法应用于所有IEnumerable&lt;&gt;

      现在我们已经确定了它们的来源,很容易理解它们为何如此不同。 Linq 增加了创建“处理流”的方法,通过每次创建新的实例来实现。

      List&lt;T&gt;.Reverse()List 的一个方法,和它的所有方法一样(例如Add)直接修改实例。

      【讨论】:

        【解决方案6】:

        IEnumerable&lt;T&gt; 有一个底层实现,可以是List&lt;T&gt;Hashtable&lt;T&gt; 或其他实现 IEnumerable 的东西。

        List&lt;T&gt; 本身实现,所以你可以直接修改那个实例。

        正如其他人所提到的,一种是扩展方法,是 Linq 的一部分,一种是直接在类型上实现的。

        【讨论】:

          猜你喜欢
          • 2010-11-06
          • 2011-06-25
          • 2011-05-31
          • 1970-01-01
          • 2011-05-15
          • 1970-01-01
          • 2014-10-12
          • 2017-11-29
          • 2015-11-06
          相关资源
          最近更新 更多