C#中的运行时TypeCasting

时间:2015-06-19 08:36:04

标签: c# .net polymorphism

IDE:VS2010,C#.NET 4.0

我想知道有没有办法以变量传递方式对对象进行类型转换,例如:

#CODE BLOCK 1  
    private void ReArrangeShapeLocation(Shape currentControl, double scalePrecentageHeight, double scalePrecentageWidth)
    {
        //here I need to type cast control according to their type

        //example code
        int cX = (currentControl as RectangleShape).Location.X;
        int cXo = (currentControl as OvalShape).Location.X;  
        //Computation code.
    }  

此处Shape类在c#namespace

中可用
Microsoft.VisualBasic.PowerPacks  

和RectangleShape和OvalShape是Shape类的子类。

所以在上面的代码中,如果我通过

ReArrangeShapeLocation(somRectrangleShape1,14,34);
ReArrangeShapeLocation(somOvelShape1,15,15);  

在这里,我在同一个函数中传递矩形和椭圆形状以获得它们在函数中的位置(参见代码块#1),我需要相应地输入Cast对象。

在c#中是否有任何方法根据子类对形状对象进行类型转换,无论我在ReArrangeShapeLocation函数中传递什么。

#CODE BLOCK 1  
    private void ReArrangeShapeLocationDYNAMIC(Shape currentControl, double scalePrecentageHeight, double scalePrecentageWidth)
    {
        //here I need to type cast control according to their type

        //example code
        int cX = (currentControl as Typeof(currentControl)).Location.X;

    }      

我知道可以使用我不想要的开关盒来完成。我也知道在c#中这可能是使用Reflaction完成的,但我不知道。

3 个答案:

答案 0 :(得分:2)

这实际上不是必需的,而且恰好是多态性的要点。从Shape派生的任何类都将具有在Shape中声明的相应属性。因此,为了获得坐标(我假设它是Shape类的一部分),将哪种形状传递给方法并不重要。

可以将基础对象强制转换为专用对象,但前提是您确定所获得的对象具有正确的类型。

例如,这有效:

Shape r = new RectangleShape();
RectangleShape r1 = r as RectangleShape();

虽然这不是:

Shape p = new PolygonShape();
RectangleShape p1 = p as RectangleShape();

我注意到Shape类没有定义坐标,但是SimpleShape类没有定义坐标,它来自Shape。由于您依赖代码中的Location属性,因此您需要确保获得的ShapeSimpleShape

您可以将方法声明更改为采用SimpleShape参数:

private void ReArrangeShapeLocation(SimpleShape currentControl, double scalePrecentageHeight, double scalePrecentageWidth)
{
    int cX = currentControl.Location.X;
}  

或者您可以保留原样并在发生错误时抛出异常:

private void ReArrangeShapeLocation(Shape currentControl, double scalePrecentageHeight, double scalePrecentageWidth)
{
    if (!(currentControl is SimpleShape))
        throw new ArgumentException("currentControl is not a SimpleShape");

    int cX = (currentControl as SimpleShape).Location.X;
}  

或者您也可以将方法扩展到处理LineShape

private void ReArrangeShapeLocation(Shape currentControl, double scalePrecentageHeight, double scalePrecentageWidth)
{
    int cX = 0;

    if (currentControl is SimpleShape)
    {
        cX = (currentControl as SimpleShape).Location.X;
    }
    else if (currentControl is LineShape)
    {
        cX = (currentControl as LineShape).X1;
    }
}  

答案 1 :(得分:0)

通过查看Shape MSDN页面,看起来Shape似乎没有Location属性......您仍然可以使用dynamic

dynamic currentControl2 = currentControl;
int cx = currentControl2.Location.X;

请注意,在这种特殊情况下,还有另一种更好的可能性,如Thorsten Dittmar所写:使用SimpleShape

答案 2 :(得分:0)

请改用SimpleShape课程。这是具有Location属性的继承对象:

private void ReArrangeShapeLocationDYNAMIC(SimpleShape currentControl, 
    double scalePrecentageHeight, double scalePrecentageWidth)
{
    int cX = currentControl.Location.X;

}