只是有一个简单的问题......任何帮助都会非常感激!
我正在写一个数据库。我有一个名为“机制”的类,它被另外两个名为“摩托车”和“汽车”的类继承。我将如何打印摩托车或汽车的内容 - 取决于用户决定进入数据库的内容?
这是我到目前为止,它给了我这个错误: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");
}
标志应该跟踪试图将哪种类型的车辆输入我的数据库 - 然后它应该将其写入文本文件..
答案 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());
}