2010-08-27 54 views
3

最近我一直在使用扩展方法来帮助我的代码更流利,但是我一直在遇到不能限制我以我想要的方式创建的功能的暴露情况。为什么扩展方法类不能嵌套是否有很好的理由?

说我有一些像这样的代码(完全由为例):

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); 
... 

在那里你可以声明一个扩展方法,这些限制似乎相当任意的给我,但我认为他们有良好的逻辑或技术的原因。如果是这样,他们是什么?

+1

不能对这个问题的技术细节发表评论。但它看起来像是在试图将功能拉大到不属于那里的扩展方法。通过存储库实现这些示例,并且问题消失。扩展*应该是全球性的。需要锁定他们的访问是一个非常糟糕的代码味道imho。 – fearofawhackplanet 2010-08-27 10:39:47

+1

我同意在嵌套类中声明“本地”扩展方法通常很有用。或者,你可以声明它们在一个单独的命名空间,所以它们不会出现在任何地方 – 2010-08-27 10:44:38

+0

我同意应该有一种方法来限制基于类(不只是命名空间)的扩展方法的范围。 – Vaccano 2012-05-16 21:53:16

回答

3

扩展方法分类不嵌套的主要原因是为了让编译器更容易找到它们(同样的原因导致它们被限制为静态类)。现在,编译器必须扫描名称空间下的所有静态类才能找到这些方法。如果允许在所有类中嵌套或使用它们,那么编译器的工作就会困难得多。此外,这可能会导致名称冲突。因为我不知道答案

例如:

public static class Foo 
{ 
    public static void DoStuff(this object param) 
    { 
    } 
    public static class Bar 
    { 
     public static void DoStuff(this object param) 
     { 
     } 
    } 
} 
0

您不想公开扩展方法的事实应该清楚地表明您的函数不应该是扩展方法。扩展方法旨在以更友好的方式公开类型中的现有功能。

+1

我的示例不是以更友好的方式公开现有功能吗?如果它是在一个单独的公共扩展类中,我不相信任何人会声称它不是扩展方法的有效用法。这只是一个扩展方法,我不希望在使用它的类之外混淆我的智能感知。 – 2010-08-27 12:52:48

+0

你是对的,它是扩展方法的有效用法。但是您现在想要改变扩展方法的实现方式,以适应IDE的便利性,这不是一个需要它的好理由。毕竟,您可以使用记事本编写C#代码。 – jvanrhyn 2010-08-27 18:06:18

相关问题