假设我有一个名为Shape的基类。然后是一些子类,如圆形和方形。
然后让我们在另一个名为GetShape的类中创建一个方法:
public Shape GetShape()
{
return new Circle();
}
好吧,我的想法是,我可以传入一个shapeType,然后返回一个强类型的Shape子类。上面的例子是对实际代码的大规模简化,但我认为它得到了重点。
那么当我调用这个方法时,它看起来像
var shapeCreator = new ShapeCreator();
Circle myCircle = shapeCreator.GetShape();
只有问题是它甚至无法运行,因为它需要演员。
这实际上有效:
Circle myCircle = (Circle) shapeCreator.GetShape();
我对这个演员阵容并不狂热,我怎么能避免它,并且仍然有办法让一个方法返回一个基类,这样我就可以返回任何兼容的子类。
答案 0 :(得分:5)
即使没有反射,您也可以使用泛型。此示例使用T
上的无参数构造函数过滤器(从Adil更改的样本):
public T GetShape<T>() where T : Shape, new()
{
return new T();
}
答案 1 :(得分:3)
没有办法解决您提出的问题。但是,你说
所以我的想法是,我可以传入一个shapeType,然后强烈地获取 返回类型化的Shape子类
你的意思是这样的:
var shape = shapecreator.GetShape(typeof(Circle));
或
var shape = shapecreator.GetShape<Circle>();
如果是这样,并且在编译时静态知道类型,只需执行
var circle = shapecreator.GetCircle();
如果类型不是静态知道的,但只能在运行时确定,则需要逻辑来决定调用哪种方法,例如:使用if
或switch
语句。话虽这么说,你也需要像演员这样的逻辑,所以这不是一个真正的劣势。
另一种选择可能是使用抽象工厂设计模式,其中ShapeFactoryBase
类具有virtual Shape Create()
方法,而派生类CircleFactory
从中继承,并覆盖Create()
方法。你仍然需要演员,你仍然需要逻辑来决定要演员的类型。
答案 2 :(得分:1)
您可以使用generic methods通过方法调用传递所需的类型。在该方法中,您可以使用Activator.Createinstance来创建要传递的类型的对象。
GetShape定义
public T GetShape<T>() where T : Shape
{
return (T)Activator.CreateInstance(typeof(T));
}
调用GetShape
Circle c = GetShape<Circle>();
Rectangle r = GetShape<Rectangle>();
修改您可以使用new Constraint
进行无反射在泛型类中将新约束应用于类型参数 创建该类型的新实例,如以下示例所示:
public T GetShape<T>() where T : Shape, new()
{
return new T();
}
答案 3 :(得分:1)
您可以简单地将形状类嵌套在GetShape
静态类中,而不是使用函数,并根据需要从该静态类创建新形状。
public static class GetShape {
public class Circle() { .. }
public class Square() { .. }
public class Triangle() { .. }
...
}
var NewShape = new GetShape.Circle();
但是,如果您不希望这样做,我会建议使用泛型。
答案 4 :(得分:0)
如果你想做某事Circle
- 具体你必须转换为这种特定类型。
您可以使用dynamic个对象,但在这种情况下,您会在编译阶段丢失类型安全检查。