为什么我不能在扩展 List 的类中调用 OrderBy?
我有一个类 Deck
,其中包含一个名为 Shuffle
的方法。
我正在努力重构 Deck
以扩展 List
,而不是让 List
Cards.OrderBy (a => Guid.NewGuid ())
有效,但 OrderBy (a => Guid.NewGuid ())
却不起作用:
错误 CS0103:当前上下文中不存在名称“OrderBy”(CS0103)
为什么这不起作用?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
将
this
添加到OrderBy
的前面,因为OrderBy
是IEnumerable
上的扩展方法,而不是List
上的公共方法。如果您在没有上下文的情况下键入OrderBy
,编译器将查找名为OrderBy
的实例或静态方法。仅当您在OrderBy
前添加IEnumerable
实例时,编译器才会找到OrderBy
。作为Deck:List
和List :IEnumerable
,使用关键字this
(对当前实例的引用)将为编译器提供定位方法Enumerable.OrderBy
所需的上下文>。从
List 继承被认为是 不好的做法;
在公共 API 中。首先,List
不是为继承而设计的,可能应该被密封
;现在为时已晚。一般来说,在使用框架类时,您应该更倾向于组合而不是继承。Add
this
to the front ofOrderBy
as inOrderBy
is an extension method onIEnumerable<T>
and is not a public method onList<T>
. If you typeOrderBy
with no context the compiler will look for an instance or static method namedOrderBy
. It is only if you prefixOrderBy
with an instance ofIEnumerable<T>
will the compiler findOrderBy
. AsDeck : List<Card>
andList<Card> : IEnumerable<Card>
, using the keywordthis
(a reference to the current instance) will give the compiler the context it needs to locate the methodEnumerable.OrderBy
.It is considered bad practice to inherit from
List<T>
in a public API. First,List<T>
was not designed for inheritance and probably should have beensealed
; too late for that now. In general, you should favor composition over inheritance when using framework classes.OrderBy
是一种扩展方法,因此它只能与IEnumerable
类型的限定符一起使用。您需要编写
this.OrderBy
。 (this
是Deck
类型的限定符,它间接继承IEnumerable
)请注意,
OrderBy
不是就地排序;如果要对现有实例进行排序,请调用Sort((a, b) => 2 - 2 * rand.Next(0, 1))
,其中rand
是Random
类的实例。注意:这是不好的做法继承
List
。相反,您应该继承System.Collections.ObjectModel.Collection
。OrderBy
is an extension method, so it can only be used with a qualifier of typeIEnumerable<T>
.You need to write
this.OrderBy
. (this
is a qualifier of typeDeck
, which indirectly inheritsIEnumerable<Card>
)Note that
OrderBy
is not an in-place sort; if you want to sort the existing instance, callSort((a, b) => 2 - 2 * rand.Next(0, 1))
whererand
is an instance of theRandom
class.Note: It is bad practice to inherit
List<T>
. Instead, you should inheritSystem.Collections.ObjectModel.Collection<T>
.OrderBy 不是
List
上的方法 - 相反,它被定义为扩展方法 Enumerable.OrderBy。因为它不是类的方法,所以你需要让编译器看到它。您可以通过调用来做到这一点:
this.OrderBy(a => Guid.NewGuid());
但是,我建议重新考虑您的方法。子类化
List
不是一个好主意 - 通过封装List
实例来实现IList
会好得多。List
应该是实现细节,而不是 API 本身的一部分。OrderBy is not a method on
List<T>
- rather, it's defined as an extension method Enumerable.OrderBy.Because it's not a method of the class, you need to make the compiler see this. You can do that by calling:
this.OrderBy(a => Guid.NewGuid());
However, I recommend rethinking your approach here. Subclassing
List<T>
is a bad idea - it's much better to implementIList<T>
by encapsulating yourList<T>
instance.List<T>
should be an implementation detail, and not part of the API itself.