72 lines
2.1 KiB
Plaintext
72 lines
2.1 KiB
Plaintext
A static field in a generic type is not shared among instances of different closed constructed types, thus ``++LengthLimitedSingletonCollection<int>.instances++`` and ``++LengthLimitedSingletonCollection<string>.instances++`` will point to different objects, even though ``++instances++`` is seemingly shared among all ``++LengthLimitedSingletonCollection<>++`` generic classes.
|
|
|
|
|
|
If you need to have a static field shared among instances with different generic arguments, define a non-generic base class to store your static members, then set your generic type to inherit from the base class.
|
|
|
|
== Noncompliant Code Example
|
|
|
|
----
|
|
public class LengthLimitedSingletonCollection<T> where T : new()
|
|
{
|
|
protected const int MaxAllowedLength = 5;
|
|
protected static Dictionary<Type, object> instances = new Dictionary<Type, object>(); // Noncompliant
|
|
|
|
public static T GetInstance()
|
|
{
|
|
object instance;
|
|
|
|
if (!instances.TryGetValue(typeof(T), out instance))
|
|
{
|
|
if (instances.Count >= MaxAllowedLength)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
instance = new T();
|
|
instances.Add(typeof(T), instance);
|
|
}
|
|
return (T)instance;
|
|
}
|
|
}
|
|
----
|
|
|
|
== Compliant Solution
|
|
|
|
----
|
|
public class SingletonCollectionBase
|
|
{
|
|
protected static Dictionary<Type, object> instances = new Dictionary<Type, object>();
|
|
}
|
|
|
|
public class LengthLimitedSingletonCollection<T> : SingletonCollectionBase where T : new()
|
|
{
|
|
protected const int MaxAllowedLength = 5;
|
|
|
|
public static T GetInstance()
|
|
{
|
|
object instance;
|
|
|
|
if (!instances.TryGetValue(typeof(T), out instance))
|
|
{
|
|
if (instances.Count >= MaxAllowedLength)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
instance = new T();
|
|
instances.Add(typeof(T), instance);
|
|
}
|
|
return (T)instance;
|
|
}
|
|
}
|
|
----
|
|
|
|
== Exceptions
|
|
|
|
If the static field or property uses a type parameter, then the developer is assumed to understand that the static member is not shared among the closed constructed types.
|
|
|
|
----
|
|
public class Cache<T>
|
|
{
|
|
private static Dictionary<string, T> CacheDictionary { get; set; } // Compliant
|
|
}
|
|
----
|