InvalidCastException未处理

时间:2011-09-19 15:30:33

标签: c# inheritance foreach reference .net

只是有一个简单的问题......任何帮助都会非常感激!

我正在写一个数据库。我有一个名为“机制”的类,它被另外两个名为“摩托车”和“汽车”的类继承。我将如何打印摩托车或汽车的内容 - 取决于用户决定进入数据库的内容?

这是我到目前为止,它给了我这个错误:InvalidCastException未处理。无法将“ConsoleApplication1.Automobile”类型的对象转换为“ConsoleApplication1.Motorcycle”类型

foreach (Mechanism m in mechanisms)
{
    //ptr = m;
    if (flagAuto == true)
    {
        Mechanism ptr = null;
        ptr = m;
        Console.WriteLine("ptr = " + ptr);
        Console.WriteLine("ptr2 = " + ptr2); 
        ptr2 = (Automobile)ptr;
        Console.WriteLine("inside Auto");
        ofp.WriteLine("" + (ptr2.getManufacturer()));
        ofp.WriteLine("" + ptr2.getModel());
        ofp.WriteLine("" + ptr2.getModelYear());
        ofp.WriteLine("" + ptr2.getVIN());
        ofp.WriteLine("" + ptr2.getInitialPurchasePrice());
        ofp.WriteLine("" + ptr2.getPurchaseDate());
        ofp.WriteLine("" + ptr2.getSizeOfEngine());
        ofp.WriteLine("" + ptr2.getTypeOfFuel());
        ofp.WriteLine("" + ptr2.getNumberOfDoors());
        ptr2 = null;
        ptr = null; 
        Console.WriteLine("finishinge Auto");
    }
    else if (flagMotor == true)
    {
        Mechanism ptr = null;
        ptr = m;
        Console.WriteLine("ptr = " + ptr);
        Console.WriteLine("ptr2 = " + ptr1); 
        Console.WriteLine("inside Motor");
        ptr1 = (Motorcycle)ptr;
        ofp.WriteLine("" + ptr1.getManufacturer());
        ofp.WriteLine("" + ptr1.getModel());
        ofp.WriteLine("" + ptr1.getModelYear());
        ofp.WriteLine("" + ptr1.getVIN());
        ofp.WriteLine("" + ptr1.getInitialPurchasePrice());
        ofp.WriteLine("" + ptr1.getPurchaseDate());
        ofp.WriteLine("" + ptr1.getSizeOfEngine());
        ofp.WriteLine("" + ptr1.getTypeOfMotorcycle());
        ptr1 = null;
        ptr = null; 
        Console.WriteLine("finishing Motor");
    }

标志应该跟踪试图将哪种类型的车辆输入我的数据库 - 然后它应该将其写入文本文件..

4 个答案:

答案 0 :(得分:3)

这意味着该标志的值是错误的。

你应该这样做:

if (m is Automobile)
{
    Automobile autoMobile = m as Automobile;
    //.. work with autoMobile
}
else if (m is Motorcycle)
{
    Motorcycle motorCycle = m as Motorcycle;
    //.. work with motorCycle 
}

顺便说一句,你在两个分支中做同样的事情。这意味着,您可以在基类(Mechanism)中实现它们,在m对象上调用这些方法。

答案 1 :(得分:2)

并非所有Mechanism都可以投放到Motorcycle。在您的特定情况下,您有Automobile的实例,并且您正尝试将其转换为Motorcycle(这是异常消息所说的内容)。您不能这样做(即使Dog都是Cat,也无法将Animal转换为ToString

为什么不覆盖Mechanism或提供Motorcycle上可以被Automobile和{{1}覆盖的方法,而不是逐个类型逻辑? }。然后您可以调用ToString或该方法,而无需担心特定类型。那是多态的!这是一个让你入门的基本例子。

class Mechanism {
     public virtual IEnumerable<string> GetDetails() {
          // assume these are all defined by Mechanism, omitted here for brevity
          yield return this.getManufacturer();
          yield return this.getModel();
          yield return this.getModelYear();
          yield return this.getVIN();
          yield return this.getInitialPurchasePrice();
          yield return this.getPurchaseDate();
          yield return this.getSizeOfEngine();
          yield return this.getTypeOfFuel();
     }
}

class Automobile : Mechanism {
     public override IEnumerable<string> GetDetails() {
          foreach(var detail in base.GetDetails()) {
               yield return detail;
          }
          yield return this.getNumberOfDoors();
     }
}

class Motorcycle : Mechanism {
     public override IEnumerable<string> GetDetails() {
         foreach(var detail in base.GetDetails()) {
             yield return detail;
         }
         yield return this.getTypeOfMotorCycle();
     }
}

然后你可以说:

foreach(var mechanism in mechanisms) {
    foreach(var detail in mechanism.GetDetails()) {
        ofp.WriteLine(detail);
    }
}

是的,很漂亮!

答案 2 :(得分:1)

嗯,简单地说,你的flagMotor对你撒谎;该对象是Automobile,正如错误消息所示,但您尝试将其强制转换为Motorcycle。你需要找出你的标志设置错误的原因。

或者你可以完全消除这些标志,并使用C#的is运算符:

if (m is Automobile) {
    // ...
} else  if (m is Motorcycle) {
    // ...
}

答案 3 :(得分:0)

正如欧内斯特·弗里德曼 - 希尔所提到的那样,目前的文字没有正确设置旗帜。

值得一提的是(没有看到你的类的完整源代码),看起来你的对象层次结构可能不是很标准的OOP。您可能应该让机制类包含从机制派生的各个类之间通用的所有成员,并覆盖两者之间可能不同的任何方法,但在两者中都有意义。这也使机制成为一个抽象的基类。

一个荒谬的简化例子如下:

public class Mechanism {
    public string Vin {get;set;}
}

public class Auto : Mechanism {
    public int NumberOfDoors {get;set;

    public override string ToString() {
        return string.Format("{0}, {1}", Vin, NumberOfDoors);
    }
}

public class Motorcycle : Mechanism {
    public string TypeOfMotorcycle {get;set; }

    public override string ToString() {
        return string.Format("{0}, {1}", Vin, TypeOfMotorcycle );
    }
}

foreach (Mechanism m in mechanisms) {
    Console.Print(m.ToString());
}