- Home /
Creating a list of singletons?
Is it possible to create a list of Singletons? For example, if I have a bunch of different types of Manager Singletons, but want to be able to sort through a list of them, can I do that?
I've tried:
public List<Manager<T>> managers; //where T : MonoBehaviour
public void AddManager<T>(Manager<T> manager) where T : MonoBehaviour
{
managers.Add(manager);
}
but it can't seem to do the conversions when trying to add to the list; even though they're both technically of the same type. I'm starting to think its just not possible.
I'm actually not sure why you would want to keep your singletons in a list, when singleton's are there to make it easier to globally access an instance of your class when you only need one instance.
With the list you are just making this harder for yourself to access the right instance. Because you need to additionally search through the list to find the right manager.
$$anonymous$$aybe your singleton approach just isn't the correct way for what you want to achieve. You could then just aswel keep an instance of each class in a list, ins$$anonymous$$d of a singleton.
$$anonymous$$aybe look into abstract classes or interfaces to suit your needs. But I would not add singletons to a list to further complicate access these instances.
I want a list so I can loop through them, that's all. They have a variable indicating if they're active, so I'd rather loop a list than check if each individual singleton is active.
Answer by Namey5 · Mar 17, 2020 at 05:16 AM
It's very difficult to understand this kind of thing from the outside without knowing the implementation - even more so when generics come into play. For instance, where and how is the type 'T' defined for use in the list? Either way, chances are you can get there through inheritance. First, declare a base class as abstract without an implementation, then inherit from it for the generic and use the base class as the list type;
public abstract class Manager { }
public class Manager<T> : Manager
{
public T testVar;
}
...
public List<Manager> testList;
public void AddManager<T> (Manager<T> man) where T : MonoBehaviour
{
testList.Add (man);
}
https://stackoverflow.com/questions/353126/c-sharp-multiple-generic-types-in-one-list
From there, you can then cast back when you need to.
Right. People always have the wrong idea about what generics are. A generic type with two different type arguments is not related in any way and the two concrete classes are (usually) not compatible. A List<ClassA>
and a List<ClassB>
are two seperate types no matter if both type arguments are derived from a common class or not.
In regard to covariance and contravariance you could restrict the usage of the type argument for only inward or outward dataflow in which care there is restricted compatibility. However any generic with an in-out type parameter is neither co- nor contravariant. This is for example the case with the List<T>
type. For more information on co- / contravariance see my answer over here.
This is very close to the correct answer (pretty much it), so I will mark it correct. If you are using the standard Singleton<$$anonymous$$onoBehaviour>
script this won't exactly work because if $$anonymous$$anager
is derived from Singleton<T>
, you'll lose the Singleton functionality, but I feel you're aware of that and this is only an issue if someone is doing as described above.
However, this can be solved if you create a Singleton class specifically for $$anonymous$$anagers, where T is $$anonymous$$anager
, and not $$anonymous$$onoBehaviour
.
Below I've written a test example that may help others further understand how they can do this:
//Contains any variables you want any manager to have.
public class $$anonymous$$anager : $$anonymous$$onoBehaviour
{
public bool active;
}
//The Singleton class specifically for $$anonymous$$anagers.
public class $$anonymous$$anager<T> : $$anonymous$$anager where T : $$anonymous$$anager
{
public static T Instance { get { if (!_instance) _instance = FindObjectOfType<T>(); return _instance; } }
static T _instance;
}
//Whatever class you want to have a list of $$anonymous$$anagers.
public class $$anonymous$$anagerList : $$anonymous$$onoBehaviour
{
public static List<$$anonymous$$anager> managers = new List<$$anonymous$$anager>();
public $$anonymous$$anager GetFirstActive$$anonymous$$anager()
{
foreach($$anonymous$$anager manager in managers)
{
if (manager.active)
return manager;
}
return null;
}
}
//An example of a $$anonymous$$anager. Adds itself to the list.
public class Dialogue$$anonymous$$anager : $$anonymous$$anager<Dialogue$$anonymous$$anager>
{
public void Start()
{
$$anonymous$$anagerList.managers.Add(this);
}
}
I should also note that this applies to any example where you need a list of Singletons. I simply used $$anonymous$$anagers as an example to help convey my situation and give context to discover a solution.
Thanks for the help!
Your answer
Follow this Question
Related Questions
Start function on a listed non mono script? 2 Answers
A node in a childnode? 1 Answer
How do I fix this error when trying to use the Watson SDK for Speech to Text? 0 Answers
Problem with arrays in a list 1 Answer
Affect every object in array. 1 Answer