我有一个类的构造函数,需要向其提供不同类型的参数。我知道我可以用不同的签名编写构造函数,但这有点痛苦。
有没有一种方法可以使参数成为两种不同类型之一:
我需要做什么:
public Line(Coordinate p1, Coordinate p2)
{}
public Line(Point3d p1, Point3d p2)
{}
public Line(Point3d p1, Coordinate p2)
{}
public Line(Coordinate p1, Point3d p2)
{}
有没有一种方法可以编写一个仅将两个参数用作Coordinate或Point3d的构造函数,而无需编写四个不同的构造函数?
答案 0 :(得分:1)
执行此操作时,您有几种选择。我的建议是要么创建一个包含共享方法和属性的接口,要么使用装箱/拆箱将参数作为对象传递并将其强制转换为所需的任何类型。
对于接口方法,您将需要定义一个公共接口:
public interface ICoordinatePoint
{
void SomeMethod();
int someAttribute;
}
然后在定义类时,实现此接口
public class Coordinate : ICoordinatePoint
public class Point3d : ICoordinatePoint
在函数中,只需将变量作为ICoordinatePoint
传递
public Line(ICoordinatePoint p1, ICoordinatePoint p2)
{
// Some stuff
}
如果要使用装箱/拆箱,则可以将p1
和p2
定义为对象:
public Line(object _p1, object _p2)
{
Coordinate p1 = (Coordinate)_p1;
Point3d p2 = (Point3d)_p2;
// Some stuff
}
编辑:如果要确保对象不是任何其他类型,则可以在投射之前检查类型:
if (p1.GetType() != typeof(Coordinate) && p1.GetType() != typeof(Point3d)
// Raise error or return
if (p2.GetType() != typeof(Coordinate) && p1.GetType() != typeof(Point3d)
// Raise error or return
答案 1 :(得分:0)
您可以将interface用作构造函数的参数。然后,您将需要提供一个将该接口作为参数实现的类。
public interface IClassInterface
{}
然后,您需要在您的类中实现该接口。
public Class : IClassInterface
{}
最后,您需要将该接口用作构造函数的参数。
public Line(IClassInterface p1, IClassInterface p2)
{}
这样,您的构造函数将只接受具有指定接口作为参数的类。
答案 2 :(得分:0)
您可以尝试使用可选参数。以下内容将允许变量的任何组合,包括所有空值。不过,您将需要在构造函数中检查所有这些组合。
public Line(Coordinate c1 = null, Coordinate c2 = null, Point3d p1 = null, Point3d p2 = null)
{}
如果您走这条路线,您可能只想在某些条件合适的情况下创建一条线。为此,请考虑以下设计模式。将构造函数设为私有,并创建静态方法以仅在满足条件的情况下返回新Line。
public class Line{
private Line(Coordinate c1 = null, Coordinate c2 = null, Point3d p1 = null, Point3d p2 = null)
{}
public static Line CreateLine(Coordinate c1 = null, Coordinate c2 = null, Point3d p1 = null, Point3d p2 = null)
{
if (/* favorable condition*/)
return new Line(c1, c2, p1, p2);
return null;
}
}
如果Coordinate和Point3d确实实现了通用接口,我也建议使用泛型
public class Line<T1, T2>
where T1: ICommonInterface
where T2: ICommonInterface
{
public Line(T1 p1, T2 p2)
{
}
}
答案 3 :(得分:0)
我们希望有一个可以同时支持Coordinate和Point3d的界面。如果两者都共享功能,则可以创建一个基类(如果我们不希望实例化它,也可以是抽象的)
public class Coordinate :IBasePoint
{
}
public class Point3d:IBasePoint
{
}
然后按如下所示使用它
public class Line
{
public Line(IBasePoint p1, IBasePoint p2){}
}
如果您可以共享常用功能,则可能要实现一个基类
public abstract class BasePoint
{
//shared logic
}
public class Coordinate:BasePoint
{
}
public class Point3d:BasePoint
{
}
然后按如下所示使用它
public class Line
{
public Line(BasePoint p1, BasePoint p2)
{
}
}
答案 4 :(得分:0)
这里大多数答案的一个假设是,您可以更新Coordinate或Point3d类,从而可以实现接口或添加基类。假设情况并非如此,则最好的解决方案可能是实现外观模式,以便将所需的Coordinate或Point3d类(或任何其他可接受的类型)的部分提取到单个简化的类或接口中。>
这使您可以使用具有强类型参数的单个构造函数,该参数完全包含您需要在类中使用的参数,而不会包含Coordinate或Point3d类附带的其他负担。