Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chose generic implementation if the type parameter is struct or class

Tags:

c#

generics

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#?

like image 594
akarnokd Avatar asked Dec 21 '15 22:12

akarnokd


Video Answer


1 Answers

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

like image 132
Yacoub Massad Avatar answered Oct 24 '22 21:10

Yacoub Massad