Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-在不编写多个定义的情况下使用多个类型作为参数?_C#_Parameters - Fatal编程技术网

C#-在不编写多个定义的情况下使用多个类型作为参数?

C#-在不编写多个定义的情况下使用多个类型作为参数?,c#,parameters,C#,Parameters,我有一个类的构造函数,需要为它提供不同类型的参数。我知道我可以用不同的签名编写构造函数,但这有点痛苦 是否有一种方法允许参数为两种不同类型之一: 我需要做的是: public Line(Coordinate p1, Coordinate p2) {} public Line(Point3d p1, Point3d p2) {} public Line(Point3d p1, Coordinate p2) {} public Line(Coordinate p1, P

我有一个类的构造函数,需要为它提供不同类型的参数。我知道我可以用不同的签名编写构造函数,但这有点痛苦

是否有一种方法允许参数为两种不同类型之一:

我需要做的是:

public Line(Coordinate p1, Coordinate p2)
    {}

public Line(Point3d p1, Point3d p2)
    {}

public Line(Point3d p1, Coordinate p2)
    {}

public Line(Coordinate p1, Point3d p2)
    {}

有没有一种方法可以在不编写四个不同的构造函数的情况下编写一个只将两个参数作为坐标或Point3d的构造函数?

您可以使用接口作为构造函数的参数。然后,您需要提供一个实现该接口的类作为参数

public interface IClassInterface
{}
然后,您需要在类中实现该接口

public Class : IClassInterface
{}
最后,您需要将该接口用作构造函数的参数

public Line(IClassInterface p1, IClassInterface p2)
{}

这样,构造函数将只接受具有指定接口的类作为参数。

执行此操作时,您有几个选项。我的建议是创建一个包含共享方法和属性的接口,或者使用装箱/取消装箱将参数作为对象传递,并将其强制转换为您需要的任何类型

public interface IClassInterface
{}
对于接口方法,您需要定义一个公共接口:

public interface ICoordinatePoint
{
    void SomeMethod();
    int someAttribute;
}
然后在定义类时,实现这个接口

public class Coordinate : ICoordinatePoint
public class Point3d : ICoordinatePoint
在函数中,只需将变量作为
icoordinationpoint
s传递即可

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

您可以尝试使用可选参数。下面将允许变量的任意组合,包括所有空值。不过,您需要在构造函数中检查所有这些组合

public Line(Coordinate c1 = null, Coordinate c2 = null, Point3d p1 = null, Point3d p2 = null)
{}
如果您走这条路线,您可能只希望在某些条件正确的情况下创建一条线。为此,考虑下面的设计模式。将构造函数设为私有,并创建一个静态方法,仅当满足条件时才返回新行

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;
    }
}
如果坐标和Point3d实现了一个公共接口,我还建议使用泛型

public class Line<T1, T2>
    where T1: ICommonInterface
    where T2: ICommonInterface
{
    public Line(T1 p1, T2 p2)
    {
    }
}
公共类行
其中T1:icommon接口
其中T2:icommon接口
{
公共线路(T1 p1、T2 p2)
{
}
}

我们希望有一个可以支持坐标和Point3d的界面。如果有两个共享的功能,那么您可以创建一个基类(如果我们不希望它被实例化,也可以是抽象的)

然后按如下方式使用它

public class Line
{
  public Line(IBasePoint p1, IBasePoint p2){}
}
public class Line
{
  public Line(BasePoint p1, BasePoint p2)
  {
  }
}
如果可以共享公共功能,则可能需要实现基类

public abstract class BasePoint
{
  //shared logic
}

public class Coordinate:BasePoint
{
}

public class Point3d:BasePoint
{
}
然后按如下方式使用它

public class Line
{
  public Line(IBasePoint p1, IBasePoint p2){}
}
public class Line
{
  public Line(BasePoint p1, BasePoint p2)
  {
  }
}

这里大多数答案的一个假设是,您能够更新坐标或Point3d类,以便实现接口或添加基类。假设情况并非如此,最好的解决方案可能是实现facade模式,以便将所需的坐标或Point3d类(或任何其他可接受的类型)的部分提取到单个简化类或接口中


这允许您拥有一个具有强类型参数的构造函数,这些强类型参数正好包含您需要在类中使用的内容,并且没有坐标或Point3d类附带的额外负担。

您可以使用Line(Object[]args)并检查选项是否与您的标准匹配
坐标
点3D
之间有什么区别?使用隐式转换运算符将其中一个转换为另一个是否有意义?这样,您只需在构造函数中显式支持其中一个。唯一真正做到这一点的方法是在继承/接口实现可用的地方和/或您可以使用泛型-如果不使整个类泛型,您就无法真正为构造函数这样做。必须编写多个构造函数(或方法)重载是内部具有强类型的最小代价。不需要强类型?只需使用
对象
。顺便说一句,如果工作相同并且可以提取到方法中,那么所有这些强类型构造函数都可以调用相同的泛型方法。接口方法是唯一可行的方法,因为OP需要构造函数只接受指定的类。对象构造函数将接受任何对象。具有可选参数的构造函数是非常疯狂的想法:
var line=新行(c1:someCoordinate,p2:somePoint)
。。但正如您所见,没有办法强制传递2个参数。。如果有人通过4级考试,应该构建什么?还是没有?我已经更新了我的帖子,为可选参数路由添加了不同的模式。