Я делал некоторое программирование в последнее время и столкнулся с проблемой, которую я нашел странным в c#. (по крайней мере, для меня)
public class Foo
{
//whatever
public class FooSpecificCollection : IList<Bar>
{
//implementation details
}
public FooSpecificCollection GetFoosStuff()
{
//return the collection
}
}
Я хочу, чтобы потребитель Foo смог получить ссылку на FooSpecificCollection, даже выполнить некоторые операции на нем. Возможно, даже установите его на некоторое другое свойство Foo или чего-то как этот, но не смочь СОЗДАТЬ экземпляр этого класса. (единственным классом, который должен смочь к instatiate этот набор, должен быть Foo.
Действительно настолько неправдоподобен мой запрос? Я знаю, что люди более умный путь определил c#, но не должен там быть такой опцией, что родительский класс может создать вложенный экземпляр класса, но никто больше не может.
До сих пор я создал решение сделать абстрактный класс или интерфейс доступным через свойство и реализовать конкретный частный класс, который не доступен больше нигде.
Это корректный способ обработать такую ситуацию.?
Встроенные классы работают так, что они, как члены внешнего класса, получают доступ к закрытым членам этого внешнего класса. класс. Но не наоборот (чего вы хотите).
Вы можете защитить конструктор FooSpecificCollection, но тогда Factory должен быть частью самого FooSpecificCollection. Он может включить внешний класс:
public class Foo
{
public class FooSpecificCollection : List<Bar>
{
private FooSpecificCollection () { }
public static FooSpecificCollection GetFoosStuff()
{
var collection = new FooSpecificCollection ();
PrepareFooSpecificCollection(collection);
return collection;
}
}
private static void PrepareFooSpecificCollection(FooSpecificCollection collection)
{
//prepare the collection
}
}
Нет, и это на самом деле не имеет смысла.
Я имею в виду, что все дело в том, чтобы вы могли потенциально вернуть другие экземпляры; но кто в любом случае будет производным от этого класса? Разумеется, никакие другие классы (потому что это было бы неправильно и подразумевало, что его не следует прятать внутри основного класса), так что ...
Сделайте вложенный класс закрытым
и сделайте возвращаемое значение GetFoosStuff
IList
вместо FooSpecificCollection
.
Кроме того, существует большая вероятность, что , полученный из List
, является ошибкой .
Решение есть, но я не думаю, что смогу использовать его в своем приложении :) Идея состоит в том, чтобы получить производный класс от FooSpecific, который является частным и может использоваться только внутри Foo, но имеет открытый конструктор, поэтому Foo может создавать его экземпляры.
public class Foo
{
//whatever
public class FooSpecific
{
// Protected contructor.
protected FooSpecific()
{
}
// All other code in here.
}
// Private helper class used for initialization.
private class FooSpecificInitHelper : FooSpecific
{
public FooSpecificInitHelper()
{
}
}
// Method in foo to create instaces of FooSpecific.
private FooSpecific CreateFooSpecific()
{
return new FooSpecificInitHelper();
}
}
Если вы создаете библиотеку для использования другими, вы можете сделать конструктор внутренним
. Любой человек вне библиотеки не сможет получить к нему доступ. Если вы беспокоитесь о вызове конструктора в своем собственном проекте, просто не вызывайте его за пределами родительского класса.
Мы постоянно создаем классы, которые не связаны напрямую с другими классами, но конструкторы не обязательно должны быть скрыты от не связанных классов. Мы (программисты) знаем, что объекты не связаны, поэтому мы никогда не создаем экземпляр одного в другом.