Если вам необходимо выполнить одно из следующих требований:
- Вы хотите, чтобы вложенный класс был запечатан,
- Вы не хотите копировать все сигнатуры методов вложенного класса в интерфейс, как в Ответ Ли ,
Я нашел решение, похожее на , опубликованное ak99372 , но без использования статического инициализатора:
public class Outer
{
private interface IPrivateFactory<T>
{
T CreateInstance();
}
public sealed class Nested
{
private Nested() {
// private constructor, accessible only to the class Factory.
}
public class Factory : IPrivateFactory<Nested>
{
Nested IPrivateFactory<Nested>.CreateInstance() { return new Nested(); }
}
}
public Nested GetNested() {
// We couldn't write these lines outside of the `Outer` class.
IPrivateFactory<Nested> factory = new Nested.Factory();
return factory.CreateInstance();
}
}
Идея состоит в том, что конструктор класса Nested
доступен только для класса Factory
, который вложен на один уровень глубже. Класс Factory
явно реализует метод CreateInstance
из частного интерфейса IPrivateFactory
, так что только те, кто может видеть IPrivateFactory
, могут вызвать CreateInstance
и получить новый экземпляр Nested
.
Код за пределами класса Outer
не может свободно создавать экземпляры Nested
без запроса Outer.GetNested()
, потому что
Outer.Nested
приватен, поэтому они не могут вызывать его напрямую
Outer.Nested.Factory
может быть создан, но не может быть приведен к IPrivateFactory
, поэтому его метод CreateInstance()
не может быть вызван.
Обратите внимание, что я бы не рекомендовал использовать этот шаблон в производственном коде, но я считаю, что в некоторых случаях полезно использовать этот рукав в своих интересах.