Ограничить экземпляры создания класса? - PullRequest
10 голосов
/ 09 августа 2009

Я использую C #. Я создал класс, который может быть включен в любой проект c # .net (для настольных компьютеров или через Интернет), но я хочу, чтобы в этом приложении моего класса было создано только 10 объектов. Если экземпляры объекта создали более 10, то это должно выдать ошибку или просто не будет работать.

Возможны две ситуации,

  1. Я включу файл myclass.cs в любой проект или
  2. Я свяжу свой класс в DLL, а затем включу его в любое приложение

В обеих ситуациях должно произойти ошибка, если в приложении создано более 10 экземпляров моего класса.

Этот вопрос задал мой учитель, он сказал мне искать ответ в интернете, я пытался, но нигде не нашел решения этой проблемы, я не слышал, что мы можем ограничивать объекты?

Возможно ли, если да, то как?

Спасибо

Ответы [ 6 ]

19 голосов
/ 09 августа 2009

Сохранить статическую переменную с количеством созданных экземпляров. Увеличивайте это число с каждой постройкой объекта. Сделайте объект ID доступным и уменьшайте это число при каждом вызове Dispose (). Если вы хотите, чтобы он был потокобезопасным, используйте Interlocked.Increment () и Interlocked.Decrement (), чтобы изменить значение этой переменной вместо ++ и -.

10 голосов
/ 09 августа 2009

Я полагаю, что вам нужна какая-то форма многотонной схемы .

Многотонный шаблон - это вариант одноэлементного шаблона, но он допускает n экземпляров объекта. Подобно тому, как класс singleton имеет статическую переменную для хранения одного экземпляра, мультитон часто реализуется со статическим массивом или картой экземпляров, в зависимости от того, как вы хотите получить доступ к экземплярам - массивы допускают только числовой доступ, но с использованием карту, вы можете предоставить строковые ключи для ваших экземпляров, сделав их именованными.

8 голосов
/ 09 августа 2009

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

Пример:

public class Foobar
{
    private static int numInstances = 0;

    public static Foobar CreateFoobar()
    {
        if (numInstances++ < 10)
        {
            return new Foobar();
        }

        return null;
    }

    protected Foobar()
    {
        ...
    }
}

Вышеуказанный метод будет отлично работать для приложения с одним экземпляром, но для приложения с несколькими экземплярами вы, вероятно, захотите использовать семафор (реализация существует в System.Threading), которая предназначена именно для такой ситуации (ограничение доступа к ресурсам / объектам). Это решает проблему нескольких экземпляров класса, запрашиваемых почти одновременно, и проверки количества не выполняются.

0 голосов
/ 10 сентября 2010

Для удаления экземпляра также создайте метод статической выгрузки (аналогично AppDomain).Имейте реализацию вызова метода unload IDisposable, который уменьшает счетчик, используя Interlocked.Decrement, а также избавляется от экземпляра.

(я предполагаю, что если вы ограничиваете количество экземпляров, которыми у вас есть ресурсы для управления этим экземпляром.)

Вы также можете использовать обобщенные элементы, чтобы разрешить повторное использование класса фабрикиограничивающие экземпляры разных классов.Используйте ограничения, чтобы требовать экземпляр для реализации IDisposible и иметь конструктор по умолчанию.Также предоставьте нестатическое свойство для возврата фактического экземпляра.


public class foo : IDisposable 
   {
   public foo() { ; }
   public string Name;

   public void Dispose()  { ; } 
   // Real class would free up instance resources
   }

  LimitedInstance< foo > li = LimitedInstance< foo >.CreateInstance();

  li.Instance.Name = "Friendly Name for instance";
  // do stuff with li

  LimitedInstance< foo >.UnloadInstance( ref li );

Единственная проблема в том, что вы не можете перегрузить оператор присваивания в C #.Поэтому, если вы сделаете следующее:


   li = null;

Вместо вызова метода unload экземпляр останется в куче, и ваш счетчик количества экземпляров не будет уменьшен до тех пор, пока не произойдет GC.

0 голосов
/ 09 августа 2009

возьмите статический счетчик в классе и сгенерируйте исключение в конструкторе класса, если count> 10

0 голосов
/ 09 августа 2009

Я бы создал статическое целое число и обновил бы его при создании нового объекта.

class YourClass
{
    static int Count = 0;

    public YourClass()
    {
       Count++;
       if(Count > 10)
       {
           //throw exception
       }
    }
}
...