InvalidCastException не было обработано - PullRequest
0 голосов
/ 19 сентября 2011

Просто быстрый вопрос ... любая помощь будет очень признательна!

Я пишу базу данных.У меня есть класс под названием «Механизм», который наследуется двумя другими классами, называемыми «мотоцикл» и «автомобиль».Как мне распечатать содержимое мотоцикла или автомобиля - в зависимости от того, что пользователь решил ввести в базу данных?

это то, что я имею до сих пор, это дает мне эту ошибку: 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 ]

3 голосов
/ 19 сентября 2011

Это означает, что значение флага неверно.

Вы должны сделать это вместо этого:

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 объекта.

2 голосов
/ 19 сентября 2011

Не все Mechanism можно привести к Motorcycle с. В вашем конкретном случае у вас есть экземпляр Automobile, и вы пытаетесь привести его к Motorcycle (это то, что говорится в сообщении об исключении). Вы не можете сделать это (A Dog не может быть преобразовано в Cat, даже если оба значения Animal).

Вместо того, чтобы делать логику типа за типом, почему бы вам просто не переопределить ToString или предоставить метод для Mechanism, который может быть переопределен с помощью Motorcycle и Automobile. Тогда вы можете просто вызывать 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);
    }
}

Да, это красиво!

1 голос
/ 19 сентября 2011

Ну, проще говоря, ваш flagMotor обманывает вас;объект - Automobile, как говорится в сообщении об ошибке, но вы пытаетесь привести его к Motorcycle.Вам нужно выяснить, почему ваши флаги установлены неправильно.

Или вы можете полностью удалить флаги и использовать оператор C # is:

if (m is Automobile) {
    // ...
} else  if (m is Motorcycle) {
    // ...
}
0 голосов
/ 19 сентября 2011

Как упоминает Эрнест Фридман-Хилл, с вашим текущим архетудом флаги установлены неправильно.

Возможно, стоит упомянуть (не видя полного источника для ваших классов), похоже,возможно, ваша иерархия объектов не совсем стандартная ООП.Вероятно, вы должны иметь класс Mechanism, содержащий все члены, которые являются общими для различных классов, производных от Mechanism, и переопределять любые методы, которые могут различаться между этими двумя, но имеет смысл иметь в обоих.Это также делает достойным доказательство того, что Механизм является абстрактным базовым классом.

Смехотворно упрощенный пример приведен ниже:

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());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...