为什么我不能在扩展List的类中调用OrderBy?
我有一个类,Deck
,其中包含一种称为Shuffle
的方法。为什么我不能在扩展List的类中调用OrderBy?
我正在致力于重构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)
为什么这个不行?
在
this.OrderBy(a => Guid.NewGuid()); // a random ordering
OrderBy
添加this
到的OrderBy
前面作为是对IEnumerable<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
;现在太迟了。一般来说,当使用框架类时,你应该赞成使用继承。
OrderBy
是一种扩展方法,因此它只能与IEnumerable<T>
类型的限定符一起使用。您需要编写this.OrderBy
。 (this
是Deck
类型,间接地继承IEnumerable<Card>
的限定符)
注意OrderBy
不是就地进行排序;如果要对现有实例进行排序,请致电Sort((a, b) => 2 - 2 * rand.Next(0, 1))
,其中rand
是Random
类的实例。
注意:这是bad practice to inherit List<T>
。相反,你应该继承System.Collections.ObjectModel.Collection<T>
。
OrderBy不是List<T>
上的方法 - 而是将其定义为扩展方法Enumerable.OrderBy。
因为它不是类的方法,所以你需要让编译器看到这个。您可以通过拨打电话:
this.OrderBy(a => Guid.NewGuid());
但是,我建议您在这里重新考虑您的方法。子类List<T>
是一个坏主意 - 通过封装List<T>
实例来实现IList<T>
要好得多。 List<T>
应该是一个实现细节,而不是API本身的一部分。
我认为你是对的(关于重新思考我的方法)。我注意到我正在'List'中重新实现几个方法/属性,比如'Count'。但我不想将我*不需要的所有方法与我所做的那些一起引入。用新方法包装我需要的方法非常简单。 – 2010-01-27 01:57:13
要理解为什么大家坚持不应该从'List'继承,请看这篇文章:http://blogs.msdn.com/kcwalina/archive/2005/09/26/474010.aspx实际上,虽然你从遗漏列表遗漏了一些东西(例如收藏修改的通知),但如果你没有在公共API中使用继承类,如果你想使用它,完全取决于你'列出'作为你的基础班。不是从'List '继承的是一个推荐,而不是一条硬性规则。 –
2010-01-27 02:02:41
感谢您的链接,@Kyralessa。该建议似乎是一个很好的建议。继承列表首先是一个糟糕的主意,而列表不是被设计为继承的事实,这使得它变得更糟。 –
2010-01-27 02:13:29