2016-04-19 6 views
2

Я новичок в C# и мой вопрос:
У меня есть класс с именемC# Еогеасп на детях абстрактного

AbstractItem

и есть 3 детей к этому классу. Мой код:

private void AddChecker(List<AbstractItem> getByChosenField) 
    { 
     if (getByChosenField == null) 
     { 
      MessageBox.Show("Entry list is currently empty."); 
     } 
     else { 
      LibraryList.Items.Clear(); // simply if there are no results then list remains empty. 
      if (getByChosenField.OfType<Reading>().Count() > 0) 
      { 
       foreach (Reading item in getByChosenField) 
       { 
        LibraryList.Items.Add(
         new MyItems 
         { 
          ItemName = item.ItemName, 
          CopyNumber = int.Parse(item.CopyNumber.ToString()), 
          Guid = int.Parse(item.Guid.ToString()), 
          TimePrinted = item.Time, 
          BestSeller = item.BestSeller, 
          Category = item.BookCategory.ToString(), 
          SubCategory = item.ReadingBookSubCategory.ToString() 
         }); 
       } 
      } 
      if (getByChosenField.OfType<Cooking>().Count() > 0) 
      { 
       foreach (Cooking item in getByChosenField) 
       { 
        LibraryList.Items.Add(
         new MyItems 
         { 
          ItemName = item.ItemName, 
          CopyNumber = int.Parse(item.CopyNumber.ToString()), 
          Guid = int.Parse(item.Guid.ToString()), 
          TimePrinted = item.Time, 
          BestSeller = item.BestSeller, 
          Category = item.BookCategory.ToString(), 
          SubCategory = item.CookingBookSubCategory.ToString() 
         }); 
       } 
      } 
      if (getByChosenField.OfType<Science>().Count() > 0) 
      { 
       foreach (Science item in getByChosenField) 
       { 
        LibraryList.Items.Add(
         new MyItems 
         { 
          ItemName = item.ItemName, 
          CopyNumber = int.Parse(item.CopyNumber.ToString()), 
          Guid = int.Parse(item.Guid.ToString()), 
          TimePrinted = item.Time, 
          BestSeller = item.BestSeller, 
          Category = item.BookCategory.ToString(), 
          SubCategory = item.ScienceBookSubCategory.ToString() 
         }); 
       } 
      } 
      if (getByChosenField.OfType<Journal>().Count() > 0) 
      { 
       foreach (Journal item in getByChosenField) 
       { 
        LibraryList.Items.Add(
         new MyItems 
         { 
          ItemName = item.ItemName, 
          CopyNumber = int.Parse(item.CopyNumber.ToString()), 
          Guid = int.Parse(item.Guid.ToString()), 
          TimePrinted = item.Time, 
          Category = "Journal", 
          SubCategory = item.JournalCategory.ToString() 
         }); 
       } 
      } 
     } 
    } 

То, что я пытаюсь сделать, это становится все значения в этом списке, который соответствует getByChosenField.
Теперь, GetByChosenField в моем случае является BookName, который возвращает все книги в списке, которые в настоящее время находятся в списке BookName.
Код, который выполняет поиск, действительно работает.
Проблема заключается в том, если у меня есть название книги Гарри Поттер внутри Cooking, а также Чтение и \ или Наука, я получаю сообщение об ошибке:

Additional information: Unable to cast object of type 'CommonBookLib.Cooking' to type 'CommonBookLib.Reading'.

Эта ошибка встречается, только тогда, когда У меня есть как минимум 2 названия книг других категорий (Чтение \ Приготовление \ Наука \ Журнал).
В случае одного названия книги все в порядке.
Что мне здесь не хватает?

+1

Есть ли причина, по которой абстрактный родитель не определяет простой элемент «SubCategory», который могут наследовать все дети. Это сделало бы код намного проще, вам понадобится только один 'foreach' вместо 3 и просто будет foreach быть' foreach (элемент AbstractItem в getByChosenField) ' –

+1

Кроме того, выполнение 4' foreach' может быть довольно медленным с большим список. Возможно, вам захочется рассмотреть возможность создания единого 'foreach (var abstractItem в getByChosenField)', затем внутри 'foreach' do' var scienceItem = abstractItem as Science; ' –

+0

@ScottChamberlain. Что вы сказали, на самом деле работает лучше сейчас. Прежде, чем я мог потенциально получить suddnely другую категорию, и теперь с var bla = item, как Type, он работает фантастически. Что это такое? В чем цель? Любой источник, чтобы понять это? – N3wbie

ответ

2

Вы почти у цели.

Вы знаете, как отфильтровать список по тем элементам определенного подтипа.

Просто применить этот фильтр к IEnumerable вы итерации

 if (getByChosenField.OfType<Reading>().Any()) // Faster than Count() > 0 
     { 
      foreach (Reading item in getByChosenField.OfType<Reading>()) 
      { 
       LibraryList.Items.Add(
        new MyItems 
        { 
         ItemName = item.ItemName, 
         CopyNumber = int.Parse(item.CopyNumber.ToString()), 
         Guid = int.Parse(item.Guid.ToString()), 
         TimePrinted = item.Time, 
         BestSeller = item.BestSeller, 
         Category = item.BookCategory.ToString(), 
         SubCategory = item.ReadingBookSubCategory.ToString() 
        }); 
      } 
     } 

Конечно, когда мы делаем это, пункт if становится излишним. Если нет элементов соответствующего типа, он просто пропустит цикл.

foreach (Reading item in getByChosenField.OfType<Reading>()) 
{ 
     // Add the Reading item 
} 
foreach(Cooking item in getByChosenField.OfType<Cooking>()) 
{ 
    //Add the Cooking item 
} 
foreach(Science item in getByChosenField.OfType<Science>()) 
{ 
    // Add the science item 
} 
+0

По какой-то причине я все еще получаю следующее: 'Дополнительная информация: Невозможно наложить объект типа« CommonBookLib.Cooking »на тип« CommonBookLib.Reading ».Я не получаю его .. если я обязательно его отфильтрую, и он работает на одно значение, чем почему более одного значения получает исключение? Кажется, что для одного значения происходит одно из условий foreach, но для двух или более он сталкивается. – N3wbie

+0

Черт! Только сейчас я увидел второе условие, которое вы сделали. Thx, вот ответ. – N3wbie

 Смежные вопросы

  • Нет связанных вопросов^_^