构造没有类/结构约束的泛型类型

时间:2016-06-05 16:55:24

标签: c# generics

我有一个通用接口的单独实现(一个用于类,一个用于结构),我希望使用一个静态的Create方法来处理构造。但我无法弄清楚如何让编译器相信我正确的类型约束。我完全明白为什么它不起作用,但我该如何解决这个问题呢?

public interface ISomething<T> { }

internal class SomethingForReferenceTypes<T> 
  : ISomething<T> where T : class { }

internal class SomethingForValueTypes<T>
  : ISomething<T> where T : struct { }

public static class Something
{
  public static ISomething<T> Create<T>()
  {
    bool TIsAReferenceType = IKnowHowToFigureThisOut();
    if (TIsAReferenceType)
      return new SomethingForReferenceTypes<T>(); // ← T is not accepted here.
    else
      return new SomethingForValueTypes<T>(); // ← T is not accepted here.
  }
}

2 个答案:

答案 0 :(得分:3)

我认为您无法直接执行此操作,但您可以轻松地使用反射来创建实例:

Type openType = TIsAReferenceType 
    ? typeof(SomethingForReferenceTypes<>)
    : typeof(SomethingForValueTypes<>);
Type constructedType = openType.MakeGenericType(typeof(T));
object ret = Activator.CreateInstance(constructedType );
return (ISomething<T>) ret;

答案 1 :(得分:1)

简短的回答是,你不能。您可以使用反射执行此操作,但为了获得最大效率,您需要为静态Create方法执行动态调度:

public static class Something<T>
{
    public static readonly Func<ISomething<T>> Create;
    static Something()
    {
        var name = typeof(T).IsValueType ? "ValueType" : "Reference";
        var method = typeof(Something<T>).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static)
                                         .MakeGenericMethod(typeof(T));
        Create = (Func<ISomething<T>>)Delegate.CreateDelegate(typeof(Func<ISomething<T>>), null, method);
    }

    static ISomething<T0> Reference<T0>()
        where T0 : class
    {
        return new SomethingForReferenceTypes<T0>();
    }
    static ISomething<T0> ValueType<T0>()
      where T0 : struct
    {
        return new SomethingForValueTypes<T0>();
    }
}

然后你可以通过Something<T>.Create()用任何T来调用它。应该比Activator.CreateInstance更有效率。