I would like to implement my generic IQueue<T> interface in an efficient way by doing one implementation if T is struct and another if T is a class.
interface IQueue<T> { ... }
class StructQueue<T> : IQueue<T> where T : struct { ... }
class RefQueue<T> : IQueue<T> where T : class { ... }
The, I'd like to have a factory method which based on T's kind returns an instance of one or the other:
static IQueue<T> CreateQueue<T>() {
    if (typeof(T).IsValueType) {
        return new StructQueue<T>();
    }
    return new RefQueue<T>();
}
Of course, the compiler indicates that T should be non-nullable/nullable type argument respectively.
Is there a way to cast T into a struct kind (and into a class kind) to make the method compile? Is this kind of runtime dispatching even possible with C#?
You can use Reflection to do it like this:
static IQueue<T> CreateQueue<T>()
{
    if (typeof(T).IsValueType)
    {
        return (IQueue<T>)Activator
            .CreateInstance(typeof(StructQueue<>).MakeGenericType(typeof(T)));
    }
    return (IQueue<T>)Activator
        .CreateInstance(typeof(RefQueue<>).MakeGenericType(typeof(T)));
}
This code uses the Activator.CreateInstance method to create queues at runtime. This method takes in the type of the object you want to create.
To create a Type that represents the generic class, this code uses the MakeGenericType method to create a closed generic Type object from the open generic types like StructQueue<>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With