Вы можете использовать шаблон, похожий на шаблон синглтона (за исключением того, что мы допускаем несколько экземпляров):
public sealed class LimitedInstantiationsClass
{
private const int _maxInstantiations = 5;
private static int _instantiations = 0;
private static object _lockObject = new object();
private LimitedInstantiationsClass()
{
}
public static bool TryGetInstance(out LimitedInstantiationsClass instance)
{
instance = null;
if (_instantiations >= _maxInstantiations)
{
return false;
}
lock (_lockObject)
{
if (_instantiations >= _maxInstantiations)
{
return false;
}
++_instantiations;
}
instance = new LimitedInstantiationsClass();
return true;
}
}
По сути, только метод TryInstance
может создать экземпляр класса *, поскольку конструктор является закрытым. В классе мы в частном порядке отслеживаем, сколько экземпляров мы предоставили. Код блокировки должен гарантировать, что этот метод является поточно-ориентированным, поэтому максимум, что мы предоставим, это _maxInstantiations (5).
Причина, по которой мы проверяем _instantiations >= _maxInstantiations
дважды, заключается в том, что это может измениться между первой проверкой и получением блокировки. Мы проводим тестирование снаружи, чтобы избежать затрат на приобретение блокировки, если больше нельзя создавать экземпляры.
TryInstance
вернет false после достижения лимита.
** Вы можете создать его в другом месте, используя Reflection, но это было бы возможно практически любым методом.
Попробуйте онлайн