12

我正在使用 C#。我创建了一个可以包含在任何 c#.net 项目(桌面或基于 Web)中的类,但我希望在我的类的该应用程序中只创建 10 个对象。如果创建的对象实例超过 10 个,那么它应该会报错,否则简单将无法工作。

可能有两种情况,

  1. 我将在任何项目中包含 myclass.cs 文件或
  2. 我将我的类捆绑在一个 DLL 中,然后将它包含在任何应用程序中

在这两种情况下,如果在应用程序中创建了超过 10 个我的类的实例,它必须通过错误。

这个问题是我的老师问的,他让我在网上搜索答案,我试过了,但没有找到任何解决这个问题的方法,我没听说我们可以限制对象?

有可能吗,如果是,那怎么办?

谢谢

4

6 回答 6

20

保留一个包含创建的实例数的静态变量。随着对象的每个构造增加该数字。使对象 IDisposable 并在每次调用 Dispose() 时递减该数字。如果您希望它是线程安全的,请使用 Interlocked.Increment() 和 Interlocked.Decrement() 来更改此变量的值,而不是 ++ 和 --。

于 2009-08-09T14:05:51.643 回答
12

我相信你想要某种形式的multiton 模式

多例模式是单例模式的一种变体,但它允许对象的 n 个实例。就像单例类有一个静态变量来保存单个实例一样,多例通常使用静态数组或实例映射来实现,具体取决于您要如何访问实例 - 数组只允许数字访问,但通过使用一个地图,您可以为您的实例提供字符串键,使它们命名。

于 2009-08-09T14:05:24.577 回答
9

您只需将工厂模式与创建的实例数的计数器一起使用,之后工厂方法将抛出异常/返回 null。

例子:

public class Foobar
{
    private static int numInstances = 0;

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

        return null;
    }

    protected Foobar()
    {
        ...
    }
}

上述方法对于单实例应用程序非常有效,但对于多实例应用程序,您可能想要使用信号量(实现存在于 中System.Threading),它正是针对这种情况(限制访问到资源/对象)。它解决了几乎同时请求类的多个实例并且计数检查失败的问题。

于 2009-08-09T14:06:04.173 回答
0

我会创建一个静态整数并在您实例化一个新对象时对其进行更新。

class YourClass
{
    static int Count = 0;

    public YourClass()
    {
       Count++;
       if(Count > 10)
       {
           //throw exception
       }
    }
}
于 2009-08-09T14:07:12.877 回答
0

在类中获取一个静态计数器,如果 count>10,则在类构造函数中抛出异常

于 2009-08-09T14:07:14.560 回答
0

为了处理实例,还创建了一个静态卸载方法(类似于 AppDomain)。让 IDisposable 的 unload 方法调用实现,该实现使用 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 发生。

于 2010-09-10T03:21:01.967 回答