Есть ли веская причина, по которой классы методов расширения не могут быть вложенными? - PullRequest
3 голосов
/ 27 августа 2010

В последнее время я часто использую методы расширения, чтобы сделать свой код более свободным, но я продолжаю сталкиваться с ситуациями, когда я не могу ограничить использование функциональности, созданной мной, так, как мне бы хотелось.

Скажем, у меня есть такой код (полностью вымышленный пример):

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 ]

3 голосов
/ 27 августа 2010

Основная причина того, что классифицированные методы расширения не являются вложенными, состоит в том, чтобы упростить их поиск компилятору (по той же причине их ограничивали статическими классами).Прямо сейчас компилятор должен сканировать все статические классы в пространстве имен, чтобы найти методы.Если будет разрешено вложение или использование их во всех классах, тогда работа компилятора будет намного сложнее.Также это может привести к конфликтам имен.

Например:

public static class Foo
{
   public static void DoStuff(this object param)
   {
   }
   public static class Bar
   {
      public static void DoStuff(this object param)
      {
      }
   }
}
0 голосов
/ 27 августа 2010

Тот факт, что вы не хотите раскрывать метод расширения, должен четко указывать на то, что ваша функция не должна быть методом расширения.Методы расширения предназначены для предоставления существующей функциональности типа более дружественным способом.

...