我有一个类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)
为什么这不起作用?
答案 0 :(得分:8)
将this
添加到OrderBy
的前面,如
this.OrderBy(a => Guid.NewGuid()); // a random ordering
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
;现在为时已晚。通常,在使用框架类时,应该优先考虑组合而不是继承。
答案 1 :(得分:3)
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>
。
答案 2 :(得分:1)
OrderBy不是List<T>
上的方法 - 相反,它被定义为扩展方法Enumerable.OrderBy。
因为它不是类的方法,所以需要让编译器看到它。您可以通过致电:
来做到这一点this.OrderBy(a =&gt; Guid.NewGuid());
但是,我建议您在此重新考虑您的方法。子类化List<T>
是个坏主意 - 通过封装IList<T>
实例来实现List<T>
要好得多。 List<T>
应该是一个实现细节,而不是API本身的一部分。