Есть ли способ ограничить создание экземпляра вложенного класса в C#? Я хочу предотвратить создание вложенного класса из любого другого класса, кроме класса вложенности, но чтобы обеспечить полный доступ к вложенному классу из другого кода.Видимость конструктора вложенных классов
ответ
Обычно я создаю интерфейс для функций, которые вы хотите предоставить другим классам, а затем создайте вложенный класс private и реализуйте этот интерфейс. Таким образом, определение вложенного класса может оставаться скрытым:
public class Outer
{
private class Nested : IFace
{
public Nested(...)
{
}
//interface member implementations...
}
public IFace GetNested()
{
return new Nested();
}
}
Короче говоря, нет, вы не можете этого сделать. Существует модификатор accessibity «public», который означает «доступный никем внутри меня или вне меня», и есть модификатор доступности «private», что означает «доступный во всем, что внутри меня». Не существует модификатора, который означает «доступный для вещи непосредственно вне меня, но не для чего-либо вне ее», и это то, что вам нужно будет пометить как конструктор. Это просто не концепция, о которой подумали дизайнеры системы типов.
Вы можете написать почему Вы хотите этого безумного вида доступности? Возможно, есть лучший способ получить то, что вы хотите.
Сверху моей головы (потому что это моя забота об этом): Реализация IAsyncResult. –
Неправильно, см. Мой ответ. – MatteoSp
@MatteoSp: Хотя я нахожу это восхитительным, что вы думаете, что я ошибаюсь в отношении функции, которую я реализовал, уверяю вас, что я прав в своем утверждении, что нет модификатора доступности, который соответствует описанию, описанному в оригинальном плакате. –
UPDATE: неправильный ответ, см комментарии
Внутренний модификатор то, что вы ищете:
public class OuterClass
{
public class NestedClass {
internal NestedClass()
{
}
}
}
NestedClass будет виден всем, но это конструктор будет доступен только для OuterClass.
Этот ответ неверен. Если у вас тогда есть 'class ThirdClass {void M() {var x = new OuterClass.NestedClass(); }} '. Помните, что оригинальный плакат хотел: «* Я хочу предотвратить создание вложенного класса из любого другого класса, кроме класса вложенности. *», И это явно не соответствует законопроекту. –
Да ... ты прав. Я не заметил, что пытался вызвать конструктор из другой сборки, поэтому работал внутренний модификатор ... – MatteoSp
Поскольку в синтаксисе C# нет ничего, вам нужно будет реализовать что-то вроде «контракта» между ними. Вы можете воспользоваться тем, что вложенный класс может получить доступ к частным поля своего родителя:
public class ParentClass
{
private static Func<FriendClass> _friendContract;
public class FriendClass
{
static FriendClass()
{
_friendContract=() => new FriendClass();
}
private FriendClass() { }
}
///Usage
public FriendClass MethodUse()
{
var fInstance = _friendContract();
//fInstance.DoSomething();
return fInstance;
}
}
Конечно, вы можете настроить контракт для работы с различными параметрами
private static Func<Arg1,Arg2,FriendClass> _friendContract;
для меня статический конструктор внутреннего класса не вызван, и я получаю nullreferenceexception –
Если вам необходимо встретиться с одним из следующие требования:
- Вы хотите, чтобы вложенный класс, чтобы быть запечатаны,
- Вы не хотите, чтобы скопировать все м вложенного класса, енят подписи в интерфейс, как в Lee's answer,
Я нашел решение, похожее на the one posted by 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
«s конструктор privated, поэтому они не могут назвать это непосредственноOuter.Nested.Factory
может инстанциируемый , но не может быть отброшено доIPrivateFactory
, поэтому его методCreateInstance()
не может быть вызван.
Обратите внимание, что я бы не рекомендовал использовать этот шаблон в производственном коде, но это трюк, который мне очень пригодился в редких случаях.
Для ответа, предложенного Джошуа Смитом, я счел необходимым заставить статический конструктор FriendClass запускаться, достигнув путем вызова пустого статического метода Initalize() на FriendClass из статического конструктора ParentClass.
Вы должны комментарий Джошуа, а не сообщение нового ответа, который на самом деле не один. –
public class Outer
{
public class Nested
{
readonly Outer Outer;
public Nested(Outer outer /* , parameters */)
{
Outer = outer;
// implementation
}
// implementation
}
public Nested GetNested(/* parameters */) => new Nested(this /* , parameters */);
}
Обратите внимание, что вы можете получить доступ к частным членам Outer from Nested.
- 1. Видимость приватно унаследованных typedefs для вложенных классов
- 2. Как работает видимость для вложенных классов Java?
- 3. Видимость повторно созданного конструктора
- 4. Kotlin видимость вложенных элементов
- 5. Видимость классов тестов
- 6. видимость среди шаблонных классов
- 7. Общая видимость внутренних классов?
- 8. Создание экземпляров классов вложенных классов
- 9. Ограничить видимость классов конкретной сборкой
- 10. C# гнездование классов и видимость?
- 11. Видимость классов в пространствах имен
- 12. Задачи конструктора классов
- 13. Параметры функции конструктора классов
- 14. Ошибка вложенных классов
- 15. Управление вложенных классов
- 16. Выбор вложенных классов CSS
- 17. Assembly.GetTypes() для вложенных классов
- 18. python несколько вложенных классов
- 19. Поиск вложенных списков классов
- 20. Порядок инициализации вложенных классов
- 21. Сериализация вложенных классов
- 22. Свойства вложенных классов Swift
- 23. Обработка вложенных классов
- 24. Путаница вложенных классов Python
- 25. проектирование вложенных шаблонных классов
- 26. Java: относительно вложенных классов
- 27. псевдонимами шаблоны вложенных классов
- 28. Область вложенных классов?
- 29. Усовершенствовать вывод вложенных классов
- 30. Сфера вложенных классов
Похоже, вы изобретаете шаблон дизайна Синглтона. –
@Bastiaan: вы имеете в виду 'внедрение'. Вы не заново изобретаете шаблоны дизайна .... – James
Объявите участников, что вы не хотите быть доступными, включая конструктор, внутренний. Это значение по умолчанию. –