Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Get a list of all runtime constructed classes of a generic class

I'm trying to make a list of all the runtime constructed classes created by a generic class. In other words, if I have a class:

public GenericCls<T> {
    public void Reset() { ... }
    ...
}

And I have code in various places like this:

GenericCls<int> gci = new GenericCls<int>();
GenericCls<String> gcs = new GenericCls<String>();
GenericCls<float> gcf = new GenericCls<float>();
...

Can I get something like this?:

Type[] allconstructed = GetAllConstructed(typeof(GenericCls<>));

which returns {GenericCls<int>,GenericCls<String>,GenericCls<float>,...}

The use case involves a generic allocator, that supports any type of object allocation (it's like new XXX(), but nicer to the garbage collector). I won't go into specifics, because it will just complicate the question. Basically, I will not know all the constructed classes at compile time, since the library is a dll intended to be used with a separate code project. So I will need some form of reflection that I can't seem to find on the interwebs.

Assembly.GetExecutingAssembly().GetExportedTypes() does not contain anything but the base generic class (i.e. typeof(GenericCls<>))

typeof(GenericCls<>).GetGenericArguments() returns only Type "T", which is not only an invalid type, but entirely useless.

Is it even possible to find all constructed classes of a generic class if you only know the generic class' type? (typeof(GenericCls<>);) I'm not sure if "constructed" is the right word - I want to know either all the concrete generic-derived classes currently active, or all of these that will ever exist (not sure how C# handles generic construction behind the scenes).

like image 242
Greg Lane Avatar asked Feb 11 '11 22:02

Greg Lane


2 Answers

@David Mårtensson: Your answer gave me an idea. I could make a static list of types in any non-generic class, and register each constructed class as it was constructed (when T is known). i.e.

static public class ConcreteList {
    static public List<Type> concrete;
}
public class GenericCls<T> {
    static GenericCls() {
        ConcreteList.concrete.Add(typeof(GenericCls<T>));
    }
}

I checked it with ConcreteList.concrete[x].GetGenericArguments(), and it's working. Oh snap.

like image 184
Greg Lane Avatar answered Nov 11 '22 09:11

Greg Lane


You might use a factory class to create instances, that way the factory class could keep a list of all created classes.

like image 24
David Mårtensson Avatar answered Nov 11 '22 08:11

David Mårtensson