C# 如果类型参数为struct或class,则选择泛型实现

C# 如果类型参数为struct或class,则选择泛型实现,c#,generics,C#,Generics,如果T是struct,我想通过一个实现,如果T是class,我想通过另一个实现,以有效的方式实现我的genericIQueue接口 interface IQueue<T> { ... } class StructQueue<T> : IQueue<T> where T : struct { ... } class RefQueue<T> : IQueue<T> where T : class { ... } 接口IQueue{…}

如果T是struct,我想通过一个实现,如果T是class,我想通过另一个实现,以有效的方式实现我的generic
IQueue
接口

interface IQueue<T> { ... }

class StructQueue<T> : IQueue<T> where T : struct { ... }

class RefQueue<T> : IQueue<T> where T : class { ... }
接口IQueue{…}
类StructQueue:IQueue其中T:struct{…}
class RefQueue:IQueue其中T:class{…}
我想要一个工厂方法,它基于T的种类返回一个或另一个的实例:

static IQueue<T> CreateQueue<T>() {
    if (typeof(T).IsValueType) {
        return new StructQueue<T>();
    }
    return new RefQueue<T>();
}
静态IQueue CreateQueue(){
if(类型(T).IsValueType){
返回新的StructQueue();
}
返回新的RefQueue();
}
当然,编译器指出T应该分别是不可为null的/可为null的类型参数

有没有办法将T强制转换为结构类(和类类)以使方法可编译?这种运行时调度甚至可以通过C#实现吗?

您可以这样做:

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)));
}
静态IQueue CreateQueue()
{
if(类型(T).IsValueType)
{
返回(IQueue)激活器
.CreateInstance(typeof(StructQueue).MakeGenericType(typeof(T));
}
返回(IQueue)激活器
.CreateInstance(typeof(RefQueue).MakeGenericType(typeof(T));
}
此代码使用在运行时创建队列。此方法接受要创建的对象的类型


要创建表示泛型类的
类型
,此代码使用从打开的泛型类型(如
StructQueue
)创建一个封闭的泛型
类型
对象,Yacoub Massad的答案是正确的,但只需稍加修改,就不需要为每次调用CreateQueue运行MakeGenericType

下面的代码对每种类型运行一次MakeGenericType,因为每种类型的
QueueFactory
都有一个单独的静态变量,即
QueueFactory。queueType
将获得
StructQueue
,而
QueueFactory.queueType
将获得
RefQueue

公共类队列工厂
{
静态类型queueType=typeof(T).IsValueType?
typeof(StructQueue).MakeGenericType(typeof(T)):typeof(RefQueue).MakeGenericType(typeof(T));
公共静态IQueue CreateQueue()
{
return(IQueue)Activator.CreateInstance(queueType);
}
}

在我的半科学测试中,它在大约十分之一的时间内创建了100万个实例。

您可以使用Reflection注意,可空值类型既不通过约束,也不通过
class
,也不通过
struct
约束。对于这种情况,您应该有第三个实现类。
public class QueueFactory<T>
{
    static Type queueType = typeof(T).IsValueType ?
         typeof(StructQueue<>).MakeGenericType(typeof(T)) : typeof(RefQueue<>).MakeGenericType(typeof(T));

    public static IQueue<T> CreateQueue()
    {
        return (IQueue<T>)Activator.CreateInstance(queueType);
    }
}