【问题标题】:Restrict class instantiation限制类实例化
【发布时间】:2018-08-29 09:14:43
【问题描述】:

在 C# 中,有没有办法停止实例化类,比如在“n”个实例化之后?这个link 没有多大帮助。

关于尝试一些东西,我正在考虑将课程设为静态,但是 'n' 实例化必须在停止实例化之前实现。是否可以通过反射实现?

【问题讨论】:

  • 如果您告诉我们您正在努力实现的目标以及到目前为止您已经尝试过的目标,我认为对您会有更好的帮助。
  • 做一个工厂。另外,您想将其限制为 1 吗?还是N?如果它是 1,那么你想要“单例模式”。
  • @John 限制是 N。我是这方面的新手;所以请多多包涵。

标签: c# instantiation encapsulation


【解决方案1】:

你可能有一个私有的静态计数器,在构造函数中增加它,如果达到你的限制就抛出一个异常。但请注意,这是一个非常奇怪且很可能是糟糕的设计。 更好的方法是工厂模式

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);
}

【讨论】:

    【解决方案2】:

    您可以使用类似于单例模式的模式(除了我们允许多个实例):

    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。

    ** 您仍然可以使用反射在其他地方创建一个,但这几乎可以使用任何方法。

    Try it online

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多