Ограничить создание экземпляров классов - PullRequest
0 голосов
/ 29 августа 2018

В C # есть ли способ остановить создание экземпляра класса, скажем, после 'n' создания экземпляров? Эта ссылка не очень помогает.

О том, чтобы попробовать что-то, я думал сделать класс статичным, но 'n' экземпляры должны быть достигнуты до их остановки. Возможно ли это через Reflection?

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Вы можете использовать шаблон, похожий на шаблон синглтона (за исключением того, что мы допускаем несколько экземпляров):

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, но это было бы возможно практически любым методом.

Попробуйте онлайн

0 голосов
/ 29 августа 2018

Вы можете иметь частный статический счетчик, увеличить его в конструкторе и выдать исключение, если ваш предел достигнут. Но обратите внимание, это очень странный и, скорее всего, плохой дизайн. Лучшим способом был бы заводской шаблон

class LimitedInstantiation
    {
        private static int instCounter = 0;
        public LimitedInstantiation()
        {
            instCounter++;
            // limit your number of instances 
            if (instCounter > 3)
            {
                throw new Exception("Limit of instances reached");
            }
        }

        ~LimitedInstantiation()
        {   
            // Reduce your number of instances in the destructor
            instCounter--;
        }
    }

Вы можете проверить, если это так:

try
{
    var instance1 = new LimitedInstantiation();
    var instance2 = new LimitedInstantiation();
    var instance3 = new LimitedInstantiation();
    // this should fail.
    var instance4 = new LimitedInstantiation();
}
catch (Exception e)
{
    Console.WriteLine(e);
}
...