代码之家  ›  专栏  ›  技术社区  ›  Martin Harris

扩展方法类不能嵌套有什么好的原因吗?

  •  3
  • Martin Harris  · 技术社区  · 14 年前

    我最近经常使用扩展方法来帮助我的代码更流畅,但是我经常遇到这样的情况:我无法以我喜欢的方式限制我所创建的功能的公开。

    假设我有一些这样的代码(完全虚构的示例):

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

    在我看来,在哪里可以声明扩展方法的这些限制是相当随意的,但我认为它们有很好的逻辑或技术原因。如果是,它们是什么?

    2 回复  |  直到 14 年前
        1
  •  3
  •   Adrian Zanescu    14 年前

    扩展方法类没有嵌套的主要原因是为了让编译器更容易找到它们(同样的原因导致它们被限制为静态类)。现在,编译器必须扫描命名空间下的所有静态类才能找到方法。如果允许在所有类中嵌套或使用它们,那么编译器的工作将更加困难。这也可能导致名称冲突。

    public static class Foo
    {
       public static void DoStuff(this object param)
       {
       }
       public static class Bar
       {
          public static void DoStuff(this object param)
          {
          }
       }
    }
    
        2
  •  0
  •   jvanrhyn    14 年前

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