我有一个通用接口的单独实现(一个用于类,一个用于结构),我希望使用一个静态的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.
}
}
答案 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更有效率。