泛型方法返回泛型派生类型的对象
本文关键字:对象 类型 派生 返回 泛型 泛型方法 | 更新日期: 2023-09-27 18:03:22
我有点纠结于c#中的泛型。考虑这段代码:
public interface A {};
public interface B : A {};
public interface C : A {};
public interface IMyInterface<in T> where T : A {};
public class FirstImpl<T> : IMyInterface<T> where T : B {};
public class SecondImpl<T> : IMyInterface<T> where T : C {};
现在我需要一些工厂,它接受一个类型并返回正确的实现:
public IMyInterface<T> Create<T>() where T : A
{
if(typeof(T) is B) {
return new FirstImpl<T>();
}
if(typeof(T) is C) {
return new SecondImpl<T>();
}
}
这在两个层面上不起作用。第一个是返回类型。第二个问题是我不能将"T"传递给第一个或第二个实现,因为它们需要更具体的类型。知道怎么解吗?
任何时候您的代码使用泛型类型或方法,并且该代码对泛型类型参数进行某种测试时,您就做错了。(恕我直言,陷入沉思更糟糕。)泛型类型的全部意义在于编写的代码使不依赖于泛型类型。
在你的例子中,一个更好的方法是这样的:
static IMyInterface<T> CreateB<T>() where T : B
{
return new FirstImpl<T>();
}
static IMyInterface<T> CreateC<T>() where T : C
{
return new SecondImpl<T>();
}
。编写不同的方法来处理每种场景。无论如何,调用者必须知道它已经在处理什么,如果基于约束的方法要起作用的话。因此,使用不同的方法名并不是问题,每个方法名在适当和各自的情况下使用。
如果上面没有解决您的特定场景,请改进问题,以便它包括一个良好的最小化,完整和可验证的代码示例,不仅显示您正在尝试使用的泛型类型,而且还显示它们将被使用的上下文
如果你不介意反射,你可以这样做:
public static IMyInterface<T> Create<T>() where T : A
{
if (typeof(B).IsAssignableFrom(typeof(T)))
{
var type = typeof(FirstImpl<>);
var boundType = type.MakeGenericType(typeof(T));
return (IMyInterface<T>) Activator.CreateInstance(boundType);
}
else if(typeof(C).IsAssignableFrom(typeof(T)))
{
var type = typeof(SecondImpl<>);
var boundType = type.MakeGenericType(typeof(T));
return (IMyInterface<T>) Activator.CreateInstance(boundType);
}
throw new ArgumentException("unknown type " + typeof(T).Name);
}
你可以在。net中试试
如果您想保持设计完整,那么最简单的方法就是使用Create<T>()
方法(如public IMyInterface<T> Create<T>() where T : A , B, C
)添加额外的约束。您可能需要一个默认情况的实现来完成该方法。
public IMyInterface<T> Create<T>() where T : A, B, C
{
if (typeof(T) is B)
{
return new FirstImpl<T>();
}
if (typeof(T) is C)
{
return new SecondImpl<T>();
}
return new DefaultImpl<T>;
}