扩展方法类不能嵌套有充分的理由吗?
我最近经常使用扩展方法来帮助使我的代码更加流畅,但我不断遇到无法按照我想要的方式限制我创建的功能的公开的情况。
假设我有一些像这样的代码(完全编造的示例):
var liveSet = allitems.Where(x => x.Status == Status.Live).Select(x => x.Name);
var deadSet = allitems.Where(x => x.Status == Status.Dead).Select(x => x.Name);
var zombieSet = allitems.Where(x => x.Status == Status.Neither).Select(x => x.Name);
我想让它更流畅,并停止重复自己:
var liveSet = allitems.SelectNameWhere(x => x.Status == Status.Live);
...
但我认为这是一个辅助方法,而不是真正的扩展,所以我想限制它的使用方式与私有方法相同:
//In the same class
private static IEnumerable<string> SelectNameWhere(
this IEnumerable<Element> items,
Func<Element, bool> predicate)
...
不幸的是我不能这样做,因为保存扩展方法的类必须是静态的。好吧,不是世界末日,我将嵌套一个私有静态类来保存该方法...当然我也不能这样做,所以我要么至少将该方法公开到内部级别,或者删除我的代码的漂亮、流畅的本质:
var liveSet = SelectNameFrom(allItems, x => x.Status == Status.Live);
...
这些关于在哪里声明扩展方法的限制对我来说似乎相当随意,但我认为它们有很好的逻辑或技术原因。如果有,它们是什么?
I've been using extension methods a lot recently to help make my code be more fluent, but I keep running into situations where I can't limit the exposure of the functionality I've created in the way I'd like.
Say I have some code like this (completely made up example):
var liveSet = allitems.Where(x => x.Status == Status.Live).Select(x => x.Name);
var deadSet = allitems.Where(x => x.Status == Status.Dead).Select(x => x.Name);
var zombieSet = allitems.Where(x => x.Status == Status.Neither).Select(x => x.Name);
I'd like to make this more fluent, and stop repeating myself:
var liveSet = allitems.SelectNameWhere(x => x.Status == Status.Live);
...
But I consider this to be a helper method, not a true extension and so I would like to limit its usage in the same way as I can a private method:
//In the same class
private static IEnumerable<string> SelectNameWhere(
this IEnumerable<Element> items,
Func<Element, bool> predicate)
...
Unfortunately I can't do this because the class that holds the extension method must be static. Okay, not the end of the world, I'll nest a private static class to hold the method... Of course I can't do that either, so I'm left either exposing this method to at least an internal level, or removing the nice, fluent, nature of my code:
var liveSet = SelectNameFrom(allItems, x => x.Status == Status.Live);
...
These limitations on where you can declare an extension method seem fairly arbitrary to me, but I assume they have good logical or technical reasons. If so, what are they?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
扩展方法类不嵌套的主要原因是为了让编译器更容易找到它们(同样的原因导致它们仅限于静态类)。现在,编译器必须扫描命名空间下的所有静态类才能找到方法。如果允许在所有类中嵌套或使用它们,那么编译器的工作就会困难得多。这也可能导致名称冲突。
例如。:
The main reason that extension method classed are not nested is to make it easier for the compiler to find them (the same reason caused them to be restricted to static classes). Right now the compiler has to scan all static classes under a namespace to find the methods. If nesting or using them in all classes would be permitted then the compiler's job would be much harder. Also that could lead to name collisions.
Eg.:
您不想公开扩展方法这一事实应该清楚地表明您的函数不应该是扩展方法。扩展方法旨在以更友好的方式公开类型上的现有功能。
The fact that you do not want to expose the extension method should be a clear indication that your function should not be an extension method. Extension methods are intended to expose existing functionality on a type in a more friendly way.