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


ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]
