限制 class 实例化
Restrict class instantiation
在 C# 中,有没有办法停止实例化 class,比如说在 'n' 实例化之后?这 link 没有多大帮助。
关于尝试一些事情,我正在考虑将 class 设置为静态,但是
'n' 实例化必须在停止实例化之前完成。是否可以通过反射?
您可能有一个私有静态计数器,在构造函数中递增它并在达到限制时抛出异常。但请注意,这是一个非常奇怪且很可能是糟糕的设计。
更好的方法是工厂模式
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);
}
您可以使用类似于单例模式的模式(除了我们允许多个实例):
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
方法可以创建 class* 的实例,因为构造函数是私有的。在 class 中,我们私下跟踪我们提供了多少实例。加锁代码是为了保证这个方法是线程安全的,所以我们最多提供的就是_maxInstantiations(5).
我们检查 _instantiations >= _maxInstantiations
两次的原因是因为这可能会在第一次检查和获取锁之间发生变化。我们在外部进行测试,以避免在无法创建更多实例时获取锁的成本。
TryInstance
达到限制后会 return false。
** 您仍然可以使用反射在别处创建一个,但几乎任何方法都可以做到这一点。
在 C# 中,有没有办法停止实例化 class,比如说在 'n' 实例化之后?这 link 没有多大帮助。
关于尝试一些事情,我正在考虑将 class 设置为静态,但是 'n' 实例化必须在停止实例化之前完成。是否可以通过反射?
您可能有一个私有静态计数器,在构造函数中递增它并在达到限制时抛出异常。但请注意,这是一个非常奇怪且很可能是糟糕的设计。 更好的方法是工厂模式
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);
}
您可以使用类似于单例模式的模式(除了我们允许多个实例):
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
方法可以创建 class* 的实例,因为构造函数是私有的。在 class 中,我们私下跟踪我们提供了多少实例。加锁代码是为了保证这个方法是线程安全的,所以我们最多提供的就是_maxInstantiations(5).
我们检查 _instantiations >= _maxInstantiations
两次的原因是因为这可能会在第一次检查和获取锁之间发生变化。我们在外部进行测试,以避免在无法创建更多实例时获取锁的成本。
TryInstance
达到限制后会 return false。
** 您仍然可以使用反射在别处创建一个,但几乎任何方法都可以做到这一点。