[英]Generic method returning objects of generic derrived types
我在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
则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>;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.