为什么我不能在扩展List的类中调用OrderBy?

时间:2010-01-27 01:47:44

标签: c# .net linq inheritance extension-methods

我有一个类Deck,其中包含一个名为Shuffle的方法。

我正在努力重构Deck以扩展List<Card>,而不是将List<Card> Cards作为属性。但是,Cards.OrderBy (a => Guid.NewGuid ())工作时,OrderBy (a => Guid.NewGuid ())不会:

Error CS0103: The name 'OrderBy' does not exist in the current context (CS0103)

为什么这不起作用?

3 个答案:

答案 0 :(得分:8)

this添加到OrderBy的前面,如

this.OrderBy(a => Guid.NewGuid()); // a random ordering

OrderByIEnumerable<T>上的扩展方法,不是List<T>上的公开方法。如果在没有上下文的情况下键入OrderBy,编译器将查找名为OrderBy的实例或静态方法。只有当OrderBy前缀为IEnumerable<T>的实例时,编译器才会找到OrderBy。作为Deck : List<Card>List<Card> : IEnumerable<Card>,使用关键字this(对当前实例的引用)将为编译器提供定位方法Enumerable.OrderBy所需的上下文。

它被视为bad practice to inherit from List<T> in a public API。首先,List<T>不是为继承而设计的,可能应该是sealed;现在为时已晚。通常,在使用框架类时,应该优先考虑组合而不是继承。

答案 1 :(得分:3)

OrderBy是一种扩展方法,因此它只能与IEnumerable<T>类型的限定符一起使用。

您需要撰写this.OrderBy。 (thisDeck类型的限定符,间接继承IEnumerable<Card>

请注意,OrderBy不是就地排序;如果要对现有实例进行排序,请调用Sort((a, b) => 2 - 2 * rand.Next(0, 1)),其中randRandom类的实例。


注意:它是bad practice to inherit List<T>。相反,您应该继承System.Collections.ObjectModel.Collection<T>

答案 2 :(得分:1)

OrderBy不是List<T>上的方法 - 相反,它被定义为扩展方法Enumerable.OrderBy

因为它不是类的方法,所以需要让编译器看到它。您可以通过致电:

来做到这一点

this.OrderBy(a =&gt; Guid.NewGuid());

但是,我建议您在此重新考虑您的方法。子类化List<T>是个坏主意 - 通过封装IList<T>实例来实现List<T>要好得多。 List<T>应该是一个实现细节,而不是API本身的一部分。