解决这个问题的一种方法是利用泛型和new()约束。
与其将构造函数表示为方法/函数,不如将其表示为工厂类/接口。如果在每个需要创建类对象的调用站点上指定new()泛型约束,则可以相应地传递构造函数参数。
对于IDrawable的例子:
public interface IDrawable
{
void Update();
void Draw();
}
public interface IDrawableConstructor<T> where T : IDrawable
{
T Construct(GraphicsDeviceManager manager);
}
public class Triangle : IDrawable
{
public GraphicsDeviceManager Manager { get; set; }
public void Draw() { ... }
public void Update() { ... }
public Triangle(GraphicsDeviceManager manager)
{
Manager = manager;
}
}
public TriangleConstructor : IDrawableConstructor<Triangle>
{
public Triangle Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
}
当你使用它的时候:
public void SomeMethod<TBuilder>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<Triangle>, new()
{
// If we need to create a triangle
Triangle triangle = new TBuilder().Construct(manager);
// Do whatever with triangle
}
你甚至可以使用显式接口实现将所有创建方法集中在一个类中:
public DrawableConstructor : IDrawableConstructor<Triangle>,
IDrawableConstructor<Square>,
IDrawableConstructor<Circle>
{
Triangle IDrawableConstructor<Triangle>.Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
Square IDrawableConstructor<Square>.Construct(GraphicsDeviceManager manager)
{
return new Square(manager);
}
Circle IDrawableConstructor<Circle>.Construct(GraphicsDeviceManager manager)
{
return new Circle(manager);
}
}
使用它:
public void SomeMethod<TBuilder, TShape>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<TShape>, new()
{
// If we need to create an arbitrary shape
TShape shape = new TBuilder().Construct(manager);
// Do whatever with the shape
}
另一种方法是使用lambda表达式作为初始化式。在调用层次结构的早期,您将知道需要实例化哪些对象(例如,当您创建或获得对GraphicsDeviceManager对象的引用时)。一旦你有了它,就传递
() => new Triangle(manager)
到后续的方法,这样他们就知道如何从那时起创建一个三角形。如果您不能确定所有可能需要的方法,您总是可以创建一个类型字典,使用反射实现IDrawable,并在字典中注册上面所示的lambda表达式,您可以将该字典存储在共享位置或传递给进一步的函数调用。