Ответ 1
Ключевым моментом здесь является то, что вложенные классы могут обращаться к закрытым полям во внешнем классе.
Так работает следующий код:
public class Foo
{
private bool _field;
public static class Extensions
{
public static bool GetField(Foo foo)
{
return foo._field;
}
}
}
Здесь вы явно передаете экземпляр класса, и статическому методу разрешен доступ к закрытому полю... кажется разумным:
bool fieldValue = Foo.Extensions.GetField(new Foo());
Однако, хотя методы расширения являются просто альтернативным синтаксисом для статических методов, они вызываются так же, как и нестатические методы экземпляра.
Теперь, если бы методы расширения были разрешены во вложенных классах, они могли бы фактически получить доступ к закрытым полям, и они были бы намного ближе к методам экземпляра. Это может привести к непредвиденным последствиям.
В итоге, если это было разрешено:
public class Foo
{
private bool _field;
public static class Extensions
{
public static bool GetField(*this* Foo foo) // not allowed, compile error.
{
return foo._field;
}
}
}
Затем вы могли бы написать следующий код, заставляя метод расширения вести себя немного больше как метод экземпляра, чем это должно быть:
var foo = new Foo();
var iGotAPrivateField = foo.GetField();
Редактировать в результате комментариев
Почему плохая идея, чтобы методы расширения были эквивалентны методам экземпляра?
В словах Эрика Липперта (выделение мое):
Итак, да, часто звучащая критика о том, что "методы расширения не являются объектно-ориентированными", является полностью правильной, но также довольно неактуальной. Методы расширения, безусловно, не являются объектно-ориентированными. Они помещают код, который манипулирует данными, далеко от кода, который объявляет данные, они не могут нарушать инкапсуляцию и общаться с закрытым состоянием объектов, для которых они кажутся методами, они плохо работают с наследованием и так далее. Это процедурное программирование в удобной объектно-ориентированной одежде.