簡體   English   中英

在沒有類/結構約束的情況下構造泛型類型

[英]Constructing generic types without the class/struct constraint

我有一個通用接口的單獨實現(一個用於類,一個用於結構),我希望使用一個靜態的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.
  }
}

我認為您將無法直接執行此操作,但是您可以輕松地使用反射來創建實例:

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

簡短的答案是,你不能。 您可以通過反射來做到這一點,但是為了獲得最大效率,您需要為靜態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更高效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM